I’ve discovered that TaskCompletionSource.SetResult(); invokes the code awaiting the task before returning. In my case that result in a deadlock.
Yes, I have a blog post documenting this (AFAIK it’s not documented on MSDN). The deadlock happens because of two things:
- There’s a mixture of
asyncand blocking code (i.e., an
asyncmethod is calling
- Task continuations are scheduled using
I recommend starting with the simplest possible solution: removing the first thing (1). I.e., don’t mix
await SendAwaitResponse("first message"); SendAwaitResponse("second message").Wait();
await SendAwaitResponse("first message"); await SendAwaitResponse("second message");
If you need to, you can
Wait at an alternative point further up the call stack (not in an
That’s my most-recommended solution. However, if you want to try removing the second thing (2), you can do a couple of tricks: either wrap the
SetResult in a
Task.Run to force it onto a separate thread (my AsyncEx library has
*WithBackgroundContinuations extension methods that do exactly this), or give your thread an actual context (such as my
AsyncContext type) and specify
ConfigureAwait(false), which will cause the continuation to ignore the
But those solutions are much more complex than just separating the
async and blocking code.
As a side note, take a look at TPL Dataflow; it sounds like you may find it useful.