我的应用程序旨在通过TCP侦听来自客户端的传入消息。我正在使用的是TCPListner和“BeginAcceptTcpClient”方法。在建立连接时,我正在做的是使用以下方法为每个连接创建一个新线程: ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClientCommNew),client);
我的问题是,当Callback函数完成其工作时,线程会发生什么。如果答案是它自己终止,我的问题是它不是,我的进程中有大量的线程挂起,否则终止该线程的最佳做法是什么。
在旁注中,有问题的客户端自己处理连接和断开连接,这意味着我必须控制它们。
修改
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);
}
答案 0 :(得分:1)
当Callback函数完成其工作时,线程会发生什么。
您可以将线程池线程视为机器人或代理等待分配给它们的任务。他们只是继续处理分配给他们的任务,并在完成任务后等待更多任务。你不需要终止它们,这个责任在于ThreadPool类
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx
答案 1 :(得分: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/