ThreadPool 行为和 TCPListener

ThreadPool behavior and TCPListener

我这样开始 TCPListener,当工作完成后我关闭 Socket。 我想知道我开始的 Thread 是不是这样

ThreadPool.QueueUserWorkItem(ConnectClientsThredProc, args);

会自我毁灭,所以我不需要任何外部控制。

有没有人很乐意解释一下我是否担心。 谢谢!

   class TCPListenerManager
    {
        TcpListener tcpListener;
        HostListenerItem hostListener;
        private bool _isServerWorking = false;

     public TCPListenerManager(HostListenerItem hostListenerItem)
     {
         hostListener = hostListenerItem;

         tcpListener = new TcpListener(IPAddress.Parse(hostListenerItem.IP4), hostListenerItem.Port);

         var t = Task.Factory.StartNew(async () =>
                {
                    await StartAsync(hostListenerItem.ClientsMax);
                });
            }

    public async Task StartAsync(int clientsMax)
    {
                    tcpListener.Start();
                    _isServerWorking = true;
                    for (int i = 0; i < clientsMax; i++)
                    {
                        if (_isServerWorking)
                        {
                            ServerConnectedEventArgs args = new ServerConnectedEventArgs();
                            args.TcpClient = await tcpListener.AcceptTcpClientAsync();
                            args.HostListener = hostListener;

                            OnServerConnected(args);
                            ThreadPool.QueueUserWorkItem(ConnectClientsThredProc, args);
                        }
   }
}


private void ConnectClientsThredProc(object obj)
{     
           var args = (ServerConnectedEventArgs)obj;

           if (args.TcpClient.Connected)
           {
              // Do some job and disconnect
              args.TcpClient.Client.Close();
              args.TcpClient.Client = null; 
           }
  }
}

ConnectClientsThredProc退出时,线程不是"gone"而是返回到池中(这就是线程池首先存在的原因)。无论如何,你确实不应该关心这个,除非你在 ConnectClientsThredProc 中执行了 long-运行 任务。如果它很长 运行 - 最好不要使用线程池线程,而是启动一个新线程(例如通过 Task.Factory.StartNew + TaskCreationOptions.LongRunning)。

此外,您使用 Task.Factory、async\await、ThreadPool.QueueUserWorkItem,所有这些都在一小段代码中混合在一起。也许您需要更好地了解这些工具是什么以及它们之间的异同(尤其是 async\await)。比如这是什么原因:

var t = Task.Factory.StartNew(async () =>
{
      await StartAsync(hostListenerItem.ClientsMax);
 });     

您启动一个 task\thread,在其中启动另一个任务,然后等待它退出 - 毫无意义。

您可以使用 Task.Run 而不是 ThreadPool.QueueUserWorkItem,效果相同。