C# 与调用响应处理程序上的睡眠相关联的.NET异步IO

C# 与调用响应处理程序上的睡眠相关联的.NET异步IO,c#,asyncsocket,C#,Asyncsocket,我有一段代码(在服务器上)使用异步方法接收套接字上的数据,如下所示: asyncRes = connectionSocket.BeginReceive(receiveBuffer, 0, RECEIVING_BUFFER_SIZE, SocketFlags.None, out error, new AsyncCallback(ReceiveDataDone), null); 在套接字的处理程序(ReceiveDataDone)中,有时会使用Thread.Sleep(X)来等待其他事情(

我有一段代码(在服务器上)使用异步方法接收套接字上的数据,如下所示:

asyncRes = connectionSocket.BeginReceive(receiveBuffer, 0, RECEIVING_BUFFER_SIZE,
    SocketFlags.None, out error, new AsyncCallback(ReceiveDataDone), null);

在套接字的处理程序(ReceiveDataDone)中,有时会使用Thread.Sleep(X)来等待其他事情(确实是有问题的实现)。我知道这是一个有问题的设计,但我想知道,由于服务器中调用了ReceiveDataDone的其他挂起套接字,生成这样的代码是否可以解释在我的应用程序中创建的线程爆炸。(当服务器处理多个连接时,创建的线程数量象征性地爆炸)。我想知道.NET套接字上的
BeginReceive
方法是如何工作的,这可以解释我看到的大量线程。

您绝对不应该在APM回调中执行任何类型的阻塞操作。这些是在线程池中运行的。线程池是为调用短期任务而设计的。如果阻塞(或执行时间较长),则会占用(有限数量的)线程并导致线程池不足。因为线程池不容易启动额外线程(事实上,启动额外线程的速度非常慢),所以您在控制线程池启动新线程的速度的时间上遇到了瓶颈

尽管回答了一个不同的问题,但我不久前给出的回答解释了同样的问题:


您绝对不应该在APM回调中执行任何类型的阻塞操作。这些是在线程池中运行的。线程池是为调用短期任务而设计的。如果阻塞(或执行时间较长),则会占用(有限数量的)线程并导致线程池不足。因为线程池不容易启动额外线程(事实上,启动额外线程的速度非常慢),所以您在控制线程池启动新线程的速度的时间上遇到了瓶颈

尽管回答了一个不同的问题,但我不久前给出的回答解释了同样的问题:


您不应该使用
线程。在线程池线程中等待时使用sleep
,这会导致线程被阻塞,并且在阻塞期间它不会接受任何进一步的工作项


您可以为这样的用例使用。它将允许
线程池
同时在等待的线程上安排其他工作

您不应使用
Thread.sleep
等待线程池中的线程。这会导致线程被阻塞,并且在阻塞期间它不会接受任何进一步的工作项


您可以为这样的用例使用。它将允许
线程池
同时在等待的线程上安排其他工作

@nos是的,我纠正了错误question@nos是的,我纠正了这个问题,我已经从回拨中取消了睡眠,情况得到了严重改善。它一次创建了超过900个线程(在一台8个hw线程的机器上),而现在它的增长速度没有超过70:-),因此,阻塞/等待行为似乎决定了线程池确实要创建大量额外的线程,但它的速度会非常慢(希望您很快停止滥用它),因此,你的应用程序在响应增加的负载时会很慢。我已经从回调中删除了睡眠,情况得到了严重改善。它一次创建了超过900个线程(在一台8个hw线程的机器上),而现在它的增长速度没有超过70:-),因此,阻塞/等待行为似乎决定了线程池确实要创建大量额外的线程,但它的速度会非常慢(希望您很快停止滥用它),因此,您的应用程序在响应增加的负载时会很慢。