C#套接字:我真的需要这么多单独的线程吗?

时间:2014-01-15 15:57:40

标签: c# multithreading sockets

我正在用C#编写服务器。 msdn.microsoft.com上的异步示例建议如下。

  1. BeginAccept侦听客户端(并在客户端调用时启动新线程)。
  2. BeginReceive从客户端接收数据(&启动一个新线程来执行此操作)。
  3. BeginSend回复向客户端发送数据(并启动另一个线程)。
  4. 此时似乎有4个单独的线程,当从我的(可能是天真的)观点来看,实际上只需要服务器继续监听2.1和与客户端进行对话。为什么我与客户端的对话需要3个线程,因为我必须在发送之前等待回复,而在等待从客户端接收数据时我不会做任何其他事情?

    干杯

2 个答案:

答案 0 :(得分:2)

BeginAccept无法启动新主题。它将处理程序附加到OS级别挂钩。没有线程可以为这项操作做好工作。 BeginReceiveBeginSend也是如此。这些都没有开始新的线程。

当他们为实际触发添加处理程序的事件时,会创建一个线程池线程来响应正在发生的操作。这里完成的CPU绑定工作通常应该很低。你在这里看到的是需要很多线程池线程,但是他们完成的工作很少,所以很快就会将它们发送回池中。

线程池设计用于此类用途。而不是为每个事件响应创建完整的线程(昂贵),您可以创建1-2个线程并不断重复使用它们依次响应所有这些事件。该池只会创建尽可能多的线程,以跟上足够小的积压。

答案 1 :(得分:1)

虽然您的主线程将围绕这些操作进行编组,但您不必自己“启动线程”。 BeginAccept是一种非阻塞方法 - .NET将立即从它返回,但在异步完成其目的时调用线程池上的回调。 线程池在您的控件之外进行了优化。