Pergunta

I have a piece of code (on a server) that uses async method to receive data on sockets like this:

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

In the handler (ReceiveDataDone) of the socket there are cases where Thread.Sleep(X) is used in order to wait for other things(questionable implementation indeed). I know this is a questionable design but I wonder if making such kind of code could explain an explosion of threads created in my application because of the other pending sockets in the server that have their ReceiveDataDone called. (when many connections are handled by the server the number of threads created figuratively explodes). I wonder how BeginReceive method on .NET sockets work, that could explain the huge number of threads I see.

Foi útil?

Solução

You absolutely should not perform any kind of blocking action in APM callbacks. These are run in the ThreadPool. The ThreadPool is designed for the invocation of short-lived tasks. If you block (or take a long time to execute) you are tying up (a finite number of) threads and causing ThreadPool starvation. Because the ThreadPool does not spin up extra threads easily (in fact, it's quite slow to start extra threads), you're bottlenecking on the timing that controls how quickly the ThreadPool is allowed to spin up new threads.

Despite answering a different question, this answer I provided a while back explains the same issue:

https://stackoverflow.com/a/1733226/14357

Outras dicas

You should not use Thread.sleep for waiting in ThreadPool Threads this causes the Thread to be blocked and It will not accept any further workitems for the time it is blocked.

You can use TimerCallback for such a use case. It will let the ThreadPool schedule other work on the waiting thread in the meantime.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top