【发布时间】:2017-12-20 09:16:30
【问题描述】:
我有一个 TcpListener 监听传入的连接,现在我基本上想问是在同一个线程中处理客户端通信还是启动一个新线程更好;所以如果有最佳实践。
我故意没有添加 try-catch 块和其他处理以保持问题简单明了。
方法一:
while(true)
{
TcpClient client = listener.AcceptTcpClient();
processData(client);
}
方法二:
while(true)
{
TcpClient client = listener.AcceptTcpClient();
new Thread(() => processData(client)).Start();
}
方法三:
while(true)
{
TcpClient client = listener.AcceptTcpClient();
Thread t = new Thread(() => processData(client));
t.Start();
t.Join();
}
之前的代码写的和方法一一样,但是processData随机抛出了ThreadAbortExceptions,从而关闭了整个服务器线程(可能是因为客户端超时,无法准确找到异常的来源为代码在 Embedded Compact 2013 机器上的 .NET Compact 框架上运行)。
【问题讨论】:
-
答案是:视情况而定。
-
它在技术上是一个广泛的问题,但是......我个人可能会考虑使用不同的线程,否则你会被困在单个线程上,其他所有东西都将排队等待操作完成跨度>
-
附带说明:在方法 1 中,可以处理第二个客户端,直到第一个客户端完成。
-
Thread-per-client 不能很好地扩展。理想情况下,您使用内置异步点不做任何选择,而是仅在数据实际可用时从 I/O 池中隐式“借用”线程。
-
我会使用一个线程。侦听器旨在一次自动连接多达 100 个连接。在 Accept 方法中,为每个新连接传递一个新套接字。一旦你得到了套接字,你就可以创建一个单独的线程来处理异步接受事件中的每个套接字。但是主代码应该是单线程的。所以从来没有解决方案是正确的。有关套接字,请参阅 msdn 示例。套接字类可以替换为任何继承套接字的类,如 TcpClient。 msdn.microsoft.com/en-us/library/w89fhyex(v=vs.100).aspx
标签: c# multithreading tcplistener