Search code examples
c#.net-coreasync-awaitsignalrtask

SignalR implementation awaits receiving task


There are two different branches with SignalR and I wonder why one of them is awaiting receiving and the other one isn't. What's the reason?

else
{
    // We're waiting on the websocket to close and there are 2 things it could be doing
    // 1. Waiting for websocket data
    // 2. Waiting on a flush to complete (backpressure being applied)

    _aborted = true;

    // Abort the websocket if we're stuck in a pending receive from the client
    socket.Abort();

    // Cancel any pending flush so that we can quit
    _application.Output.CancelPendingFlush();
}

vs

else
{
    Log.WaitingForClose(_logger);

    // We're waiting on the websocket to close and there are 2 things it could be doing
    // 1. Waiting for websocket data
    // 2. Waiting on a flush to complete (backpressure being applied)

    using (var delayCts = new CancellationTokenSource())
    {
        var resultTask = await Task.WhenAny(receiving, Task.Delay(_options.CloseTimeout, delayCts.Token));

        if (resultTask != receiving)
        {
            // Abort the websocket if we're stuck in a pending receive from the client
            _aborted = true;

            socket.Abort();

            // Cancel any pending flush so that we can quit
            _application.Output.CancelPendingFlush();
        }
        else
        {
            delayCts.Cancel();
        }
    }
}

Solution

  • They're waiting on 2 different things:

    1. There's a task reading from the websocket and writing to the application pipe
    2. There's a task reading from the application pipe and writing to the websocket.

    The first branch is handling 1. The second branch is handling 2.

    Hopefully the comments are explanatory. They detail the situations where either side could be stuck and what we abort/cancel as a result.