【问题标题】:C# TCP Client in new thread?新线程中的 C# TCP 客户端?
【发布时间】: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


【解决方案1】:

我主要想问是在同一个线程中处理客户端通信好还是启动一个新线程好;所以如果有最佳实践。

当您使用带有套接字的线程时,您可以在每次处理套接字的线程暂停时阻塞 I/O 通道。而且,您的第一种情况优于第三种情况,因为您的程序不需要更改线程。

因此,根据我的经验,处理多个套接字的最佳方法是使用单个线程及其异步方法。它比套接字的多线程更快、更安全。使用这种技术,您可以优化机器资源并避免线程竞争它们。

查看我的answer,了解如何在套接字中使用异步方法。在这种情况下,我按小时处理了 15k 个套接字请求,并且处理器的使用率不超过 1%。

【讨论】:

    猜你喜欢
    • 2015-04-05
    • 1970-01-01
    • 2012-09-26
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 2014-03-04
    相关资源
    最近更新 更多