Why doesn't using the asynchronous programming model in .NET throw StackOverflow exceptions?

For example, we call BeginReceive and have a callback method that BeginReceive executes when it is complete. If this callback method calls BeginReceive again, it will be very similar to recursion. As it does not cause stackoverflow exception. Sample code from MSDN:

private static void Receive(Socket client) {
    try {
        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = client;

        // Begin receiving the data from the remote device.
        client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReceiveCallback), state);
    } catch (Exception e) {
        Console.WriteLine(e.ToString());
    }
}

private static void ReceiveCallback( IAsyncResult ar ) {
    try {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.
        StateObject state = (StateObject) ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0) {
            // There might be more data, so store the data received so far.
        state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));

            // Get the rest of the data.
            client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
                new AsyncCallback(ReceiveCallback), state);
        } else {
            // All the data has arrived; put it in response.
            if (state.sb.Length > 1) {
                response = state.sb.ToString();
            }
            // Signal that all bytes have been received.
            receiveDone.Set();
        }
    } catch (Exception e) {
        Console.WriteLine(e.ToString());
    }
}
+5
source share
4 answers

BeginReceive , -. , , BeginReceive , ReceiveCallback .
IO , , . " , - ", . .

+3

, , BeginReceive, , , .

+3

BeginReceive - . , , , . , - . , , .

, , . , -, - .

+2

client.BeginReceive(state.buffer,0,StateObject.BufferSize,0, 
    new AsyncCallback(ReceiveCallback), state);

does not automatically call the ReceiveCallback method, this method is called when the operation is completed.

Meanwhile, the method that is called BeginReceivecontinues to be executed, doing everything that it does, and returns with joy, thereby removing itself from the stack.

When you use recursion, each call adds a stack frame (see the comment), which is not set until the called method returns, so the stack will grow until the recursion is complete.

+1
source

All Articles