在引擎盖下的阻止任务中取消令牌

时间:2015-12-11 10:20:41

标签: c# .net multithreading task-parallel-library

我有两个按钮可以启动和停止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?没有ManualResetEventManualResetEventSlim?我能够在服务器关闭和服务器重启之间切换。引擎盖下发生了什么?我的定位是.NET 4.0

1 个答案:

答案 0 :(得分:3)

  

那么点击取消按钮如何杀死taskListener?

当您在取消事件处理程序中调用TcpListener.Stop时,它会在内部关闭基础Socket,然后引发SocketException。 <{1}}所有阻止了这个异常,这只会破坏循环。

文档明确说明了这一点(强调我的):

  

停止关闭监听器。中的任何未接受的连接请求   队列将丢失。 等待连接的远程主机   接受将抛出SocketException。您负责关闭   您单独接受的连接。

您可以通过在catch块中打印出例外来看到这一点:

catch
相关问题