使用 .net 5 与任务(不是线程)的 TCP 连接

Posted

技术标签:

【中文标题】使用 .net 5 与任务(不是线程)的 TCP 连接【英文标题】:TCP connection with Tasks (not Threads) with .net 5 【发布时间】:2021-09-22 06:06:24 【问题描述】:

我正在创建一个基于 TCP 连接的小应用程序。为此,我必须创建与我拥有的端口一样多的“侦听器”。

我需要不断地监听新消息,所以我创建了一个包含所有监听器的 for 循环。

public void ListenDataAsync(int[] ports)
        
            IPAddress ipAddress = IPAddress.Parse(Constants.host);

            /*Create the Clients*/
            List<Task> tasks = new List<Task>();
            for (var i = 0; i < ports.Length; i++)
            
                tcpListeners[i] = new TcpListener(ipAddress, ports[i]);

                tcpListeners[i].Start(); 
                var t = Task.Run(() => DoBeginAcceptTcpClient(tcpListeners[i]));
                Task.Delay(1000);
                tasks.Add(t);
            
            Task.WaitAll(tasks.ToArray());
            tasks.Clear();
        

private void DoBeginAcceptTcpClient(TcpListener listener)
        
            if (listener != null)
            
                // Set the event to nonsignaled state.
                tcpClientConnected.Reset();

                // Start to listen for connections from a client.
                Console.WriteLine("Waiting for a connection...");

                // Accept the connection.
                listener.Start();
                // BeginAcceptSocket() creates the accepted socket.
                listener.BeginAcceptTcpClient(
                    new AsyncCallback(DoAcceptTcpClientCallback),
                    listener);

                // Wait until a connection is made and processed before continuing.
                tcpClientConnected.WaitOne();

            
        

就我而言,我有两个端口,因此将创建两个侦听器。

使用线程,并发可以正常工作,但是我想使用任务而不是线程

主要发生的情况是“等待连接”消息并不总是正确处理。它必须显示两次......有时它会出现一次、没有出现或出现两次。

有人知道这可能是什么原因吗?

好像和任务有关的东西……

提前致谢:)

【问题讨论】:

不要思考线程。不要想任务。考虑一下,不要只调用BeginAcceptTcpClient 并知道何时 接受调用完成,系统将找到一个线程来执行您的DoAcceptTcpClientCallback 方法。如果我的解释正确,您当前的问题可能是由于您关闭了 i 循环变量,但我强烈建议您简化 如果我这样做,系统会停止,它不是并发的......我需要监听器之间的并发。 系统不会自行停止。它停止是因为你正在刹车。例如。目前尚不清楚为什么您有等待连接发生的代码。拥抱异步,不要认为你需要创建线程、任务或任何 tcpClientConnected 用于暂停活动和停止工作的东西。 【参考方案1】:

你只需要做:

await Task.Run(() => DoBeginAcceptTcpClient(tcpListeners[i])

【讨论】:

以上是关于使用 .net 5 与任务(不是线程)的 TCP 连接的主要内容,如果未能解决你的问题,请参考以下文章

菜鸟之旅——学习线程(Task)

Python网络编程之多任务版TCP服务端程序开发

Java如何判断线程池所有任务是不是执行完毕

net.tcp 绑定上的线程不足 - TCP 错误代码 10061

使用线程的并行 TCP 连接

.net开发中,为何将100多个任务放入线程池却只有一个线程顺序执行