Lately I’ve been trying to include a call to a REST service using the WebAPI client to a library already used from inside both an ASP.NET page and a WCF service.
The problem with mixing sync and async
Of course I started with an async/await code:
HttpResponseMessage response = await client.PostAsJsonAsync(GetUpdateUri(), payload);
Unfortunately both consumers were synchronous, so I had to wait for the async to complete before going on with the execution: so I did something that proved to be wrong (the following methods calls the line above):
SendPayloadAsync(payload).Wait();
Deadlock: this never completes as ASP.NET is blocking the context thread waiting for the webapi call to complete, which waits for the thread to be free so it can complete.
How to make a synchronous web api call
What I should have done, instead, would have been to change the ASP.NET page to be an async page (using the Page.RegisterAyncTask) and also change the WCF service to be async, and use the async/await from top to bottom as is best practice. In my case it was too complex and would have required touching code developer by others and already working, so I simply avoided starting the “async chain”:
HttpResponseMessage response = client.PostAsJsonAsync(GetUpdateUri(), payload).Result;
Async/Await resources
On the other end I realized I don’t know enough about the async way of coding, and I spent some time reading some good references, mostly by “async-guru” Stephen Cleary.
- Async and Await: introductory and basic article
- HttpClient.GetAsync(…) never returns when using await/async: question on StackOverflow and good answer that explains the problem I experienced above
- Don't Block on Async Code: a better explanation of the same concept answered in the question above
- Best Practices in Asynchronous Programming: a list of best practices in async programming (Avoid Async void, Async all the way, Configure Context)
- Await, and UI, and deadlocks! Oh my!: more about locking and deadlocks
- It's All About the SynchronizationContext: longer and more theoretical article on context and synchronization of threads