取消引擎盖下阻塞任务内的令牌
本文关键字:任务 令牌 引擎 取消 | 更新日期: 2023-09-27 18:26:22
我有两个按钮可以启动和停止TcpListener
。
private void buttonStartServer_Click(object sender, EventArgs e)
{
ThreadPool.SetMinThreads(50, 50);
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
_listener = new TcpListener(ipAddress, 5000);
cancelSource = new CancellationTokenSource();
CancellationToken token = cancelSource.Token;
var taskListener = Task.Factory.StartNew(
(t) => Listener(token),token,TaskCreationOptions.LongRunning);
}
void Listener(CancellationToken token)
{
_listener.Start();
while (!token.IsCancellationRequested)
{
TcpClient c;
try
{
c = _listener.AcceptTcpClient();
}
catch
{
break;
}
Task t = Task.Factory.StartNew(() => Accept(c))
.ContinueWith(ant => richTextBoxMessage.AppendText(ant.Result), _uiScheduler);
}
}
private void buttonStopServer_Click(object sender, EventArgs e)
{
cancelSource.Cancel();
_listener.Stop();
richTextBoxMessage.AppendText("Server shutdown");
}
Accept
是从TcpClient读取的某种方法。我的问题是,在我点击按钮停止服务器之前,我的服务器在被阻止了
try {c = _listener.AcceptTcpClient();}
那么点击取消按钮是如何杀死taskListener
的呢?没有ManualResetEvent
或ManualResetEventSlim
?我可以在服务器关闭和服务器重新启动之间切换。引擎盖下面发生了什么事?我的目标是.NET 4.0
那么,单击取消按钮是如何杀死taskListener的呢?
当您在取消事件处理程序中调用TcpListener.Stop
时,它将在内部关闭基础Socket
,并引发一个SocketException
。这个异常被您的catch
all块所吞噬,这只会破坏循环。
文件明确说明了这一点(重点是我的):
Stop关闭侦听器。中任何未接受的连接请求队列将丢失等待连接的远程主机accepted将引发SocketException您负责结账您单独接受的连接。
您可以通过打印catch
块中的异常来看到这一点:
TcpClient c;
try
{
c = _listener.AcceptTcpClient();
}
catch (SocketException e)
{
Debug.WriteLine("Socket exception was raised: {0}", e);
if (e.SocketErrorCode == SocketError.Interrupted)
Debug.WriteLine("Blocking listen was interrupted");
}