I recently came across a strange bug in my async code. I was calling a blocking method on a COM control, which appeared to allow my async continuations to run while it was blocking.
Consider example code (illustrative purposes only)
public async void Main()
{
//assume some single threaded dispatcher. eg. WpfDispatcher
Task doAsyncTask = DoAsync();
Console.WriteLine("Start synchronous");
CallSomeCOMControl();
Console.WriteLine("End synchronous");
await doAsyncTask;
}
public async Task DoAsync()
{
Console.WriteLine("Start async");
await Task.Delay(1);
Console.WriteLine("End async");
}
In normal circumstances I would expect the following output:
Start async
Start synchronous
End synchronous
End async
What I was effectively seeing was:
Start async
Start synchronous
End async
End synchronous
Now I do not have the source for the COM control, but I do know that is a very old C++ control that has no notion of async/await. It is however an Active-X control.
I do not know the implementation details of the .Net RCW, but I am assuming that some kind of message pumping must be going on to allow the control to work. I am also assuming that this pumping is allowing my continuations to run.
Are my assumptions correct? And are the any other circumstances that I should be aware of where my supposedly synchronous code could get interrupted?