线程池行为和TCPListener

本文关键字:TCPListener 线程 | 更新日期: 2023-09-27 18:15:45

我像这样开始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; 
           }
  }
}

线程池行为和TCPListener

ConnectClientsThredProc退出时,线程不是"消失",而是返回到线程池(这就是为什么首先存在线程池)。无论如何,您不应该关心这个问题,除非您在ConnectClientsThredProc中执行了长时间运行的任务。如果是长时间运行-最好不要使用线程池线程,而是启动一个新的线程(例如通过Task.Factory.StartNew + TaskCreationOptions.LongRunning)。

同样,您使用Task.Factory, async'await, ThreadPool.QueueUserWorkItem,所有这些都在一小段代码中混合在一起。也许您需要更好地理解这些工具是什么以及它们之间的相似点和不同点(特别是async'await)。例如,这是什么原因:

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

你启动一个任务线程,在其中你启动另一个任务,然后等待它退出——这没什么意义。

您可以使用Task.Run来代替ThreadPool.QueueUserWorkItem,具有相同的效果