It is known that synchronous waiting on an async method leads to deadlocks (see, for example Don't Block on Async Code)
I have the following code in an event handler for a button-click in a Windows Forms application (i.e. the code is invoked with a UI SynchronizationContext
installed).
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.google.com"));
Task<HttpResponseMessage> t = client.SendAsync(request);
t.Wait();
var response = t.Result;
I fully expected the code to deadlock on clicking the button. However, what I actually see is synchronous waiting - the dialog becomes unresponsive for a while, and then accepts events as usual.
I consistently see deadlocks when I try to synchronously wait on client async methods. However, synchronously waiting on library async methods like SendAsync
or ReadAsByteArrayAsync
seems not to deadlock. Can someone explain this behaviour?
Don't implementations of async methods in .NET libraries use await statements internally, so that the continuations have to be marshalled back to the original SynchronizationContext?
Note: If I define a client method, say
public async Task<byte[]> wrapperMethod()
{
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.google.com"));
var response = await client.SendAsync(request);
return await response.Content.ReadAsByteArrayAsync();
}
and then say byte[] byteArray = wrapperMethod().Result;
in the button click handler, I do obtain a deadlock.