TcpClient BeginRead not spawning new thread RRS feed

  • Question

  • Hello

    I have a server app that uses System.Net.Sockets.TcpClient to allow many clients apps to connect to it.

    The server listens for message from the clients and performs an action depending on the message.

    I have had the server running for several days, after which one of the client objects on the server ran into a thread deadlock. I attached the debugger to the app and looked at the threads to determine what had cause the deadlock.

    I noticed that on one of the deadlocked threads I was calling GetStream.BeginRead. I assumed this would spawn a new thread from the thread pool and would execute the function passed in 'callback as ASyncCallback'. However, when I looked at the callstack for the thread it read 1:BeginRead, 2:callback function, 4:BeginRead, 5:callback function. I do restart the BeginRead process in the callback function to get the next message, but what surprised me was the the callback function was being executed on the same thread that called BeginRead and does not spawn a new thread.

    Here is an image of the callstack for one of the threads (blnBeginTCPRead calls GetStream.BeginRead and my ASyncCallback function is ReceiveMessageFromClient):


    Can anyone confirm this is the correct behaviour of BeginRead? Should I assume that BeginRead can actually execute the callback function within the BeginRead statement, and on same thread? Could something else I do cause this to happen? Is the thread pool being corrupted?

    Many thanks

    Paul Bell
    • Moved by Wenlong Dong - MSFT Wednesday, October 1, 2008 2:39 PM This post is regarding System.Net. (Moved from .NET Remoting and Runtime Serialization to .NET Framework Networking and Communication)
    • Edited by kerplunkwhoops Wednesday, October 1, 2008 5:39 PM
    Wednesday, October 1, 2008 1:52 PM

All replies

  • That behaviour is allowed by the spec -- though its not terribly well documented. :-,(  I first read about in the "Framework Design Guidelines" book.  One can check the IAsyncResult.CompletedSynchronously property to see if the callback was called on the same thread (etc).

    This behaviour is matching the underlying platform behaviour.  When one initiates an IOCP operation in Windows it can complete immediately and in that case the function returns a boolean stating that.  In that case the callback method is *not* called, but the result *has* been updated.  BTW this case can occur for instance when doing a read and the data is immediately available; its a performance optimisation to not have to start up the other thread etc.  In .NET of course the APM pattern has to be followed so the callback *is* called, but "synchronously".

    http://www.alanjmcf.me.uk/ Please follow-up in the newsgroup. If I help, mark the question answered
    Sunday, October 5, 2008 9:56 PM