1

我的应用程序旨在通过 TCP 侦听来自客户端的传入消息。我使用的是 TCPListner 和“BeginAcceptTcpClient”方法。在建立连接时,我正在做的是使用以下方法为每个连接创建一个新线程: ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClientCommNew), client);

我的问题是,当回调函数完成工作时线程会发生什么。如果答案是它自己终止,我的问题是它不是,我的进程中有大量线程挂起,否则终止线程的最佳做法是什么。

附带说明一下,有问题的客户端按自己的方式处理连接和断开连接,这意味着我必须控制它们。

编辑

public void Init() 
{
     this.tcpListener = new System.Net.Sockets.TcpListener(IPAddress.Parse("0.0.0.0"), 1000);
     this.listenThread = new Thread(new ThreadStart(ListenForClients));
}

private void ListenForClients()
{
     this.tcpListener.Start();
     StartAccept();
}

public void StartAccept()
{
     this.tcpListener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), tcpListener);

}

public void DoAcceptTcpClientCallback(IAsyncResult ar)
{
     StartAccept();
     TcpListener listener = (TcpListener)ar.AsyncState;
     TcpClient client = listener.EndAcceptTcpClient(ar);
     ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClientCommNew), client);
}

private static void HandleClientCommNew(object stateInfo)
{
     TcpClient tcpClient = (TcpClient)stateInfo;
     AsyncCallback callback = null;
     callback = ar =>
     {
          bytesRead = clientStream.EndRead(ar);
          clientStream.BeginRead(message, 0, 4500, callback, null);
     }

     clientStream.BeginRead(message, 0, 4500, callback, null);
}
4

2 回答 2

1

当回调函数完成它的工作时线程会发生什么。

您可以将线程池​​线程视为等待分配任务的机器人或代理。他们只是继续处理分配给他们的任务,并在任务完成后等待更多任务。您不需要终止它们,该责任在于 ThreadPool 类

http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

于 2013-10-04T08:51:04.220 回答
0

当您将一个方法排队到 ThreadPool 中时,它将被线程池中的一个线程拾取。当方法结束时,线程将等待另一个作业。您应该在 ThreadPool 上排队长时间运行的作业,例如等待接收数据。处理线程池中排队的作业的线程有限。因此,如果您有ThreadPool.GetMaxThreads客户端,您的应用程序将无法处理更多客户端。


您不应该使用 ThreadPool 进行连接。

而是使用异步 BeginReceive/EndReceive。因为这些使用I/O 完成端口 http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx并且在等待时不要阻塞 ThreadPool 线程。当读取一些数据时,一个新的作业将在 ThreadPool 上排队。(所以它不在那儿等着)

伪:

StartListening() <-----------------------------------------------+
{                                                                |
    BeginAcceptTcpClient(... EndListening); >----+               |
}                                                |               |
                                                 |               |
EndListening() <---------------------------------+               |
{                                                                |
    TcpClient client = EndAcceptTcpClient(..);                   |
                                                                 |
    StartClientReceiving(client); >--------------------------+   |
                                                             |   |
    StartListening(); >-------------------------------------/#\--+
}                                                            |
                                                             |
StartClientReceiving(TcpClient client) <---------------------+
{                                                          \
    client.BeginReceiving(....EndClientReceiving) >---+    |
}                                                     |    |
                                                      |    |
EndClientReceiving() <--------------------------------+    |
{                                                          |
    // if no datareceived, disconnect.                     |
    // HandleData                                          |
    StartClientReceiving(); >------------------------------+
}

我的博客上有一个套接字侦听器/阅读器的示例:http: //csharp.vanlangen.biz/network-programming/async-sockets/

于 2013-10-04T08:56:57.847 回答