【发布时间】:2010-11-13 12:17:35
【问题描述】:
我有这个代码...
internal static void Start()
{
TcpListener listenerSocket = new TcpListener(IPAddress.Any, 32599);
listenerSocket.Start();
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
那么我的回调函数是这样的……
private static void AcceptClient(IAsyncResult asyncResult)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
现在,我调用 BeginAcceptTcpClient,然后过一段时间我想停止服务器。为此,我一直在调用 TcpListener.Stop() 或 TcpListener.Server.Close()。然而,这两个都执行我的 AcceptClient 函数。当我调用 EndAcceptTcpClient 时,这会引发异常。解决此问题的最佳做法是什么?一旦我调用了 stop,我就可以放一个标志来停止 AcceptClient 的执行,但我想知道我是否遗漏了什么。
更新 1
目前我已通过将代码更改为如下所示对其进行了修补。
private static void AcceptClient(IAsyncResult asyncResult)
{
if (!shutdown)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
}
private static bool shutdown = false;
internal static void Stop()
{
shutdown = true;
listenerSocket.Stop();
}
更新 2
我更改了它以暗示 Spencer Ruport 的答案。
private static void AcceptClient(IAsyncResult asyncResult)
{
if (listenerSocket.Server.IsBound)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
}
【问题讨论】:
-
你不必排队另一个线程来做处理工作;您可以只调用 EndAcceptTcpClient 来告诉侦听器它已被处理,然后在它之后调用 BeginAcceptTcpClient 来安排另一个处理。使用当前线程处理刚刚收到的请求。