I came across some best practices for asynchronous programming using c#'s async/await keywords (I'm new to c# 5.0).
One of the advices given was the following:
Stability: Know your synchronization contexts
... Some synchronization contexts are non-reentrant and single-threaded. This means only one unit of work can be executed in the context at a given time. An example of this is the Windows UI thread or the ASP.NET request context. In these single-threaded synchronization contexts, it’s easy to deadlock yourself. If you spawn off a task from a single-threaded context, then wait for that task in the context, your waiting code may be blocking the background task.
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
If I try to dissect it myself, the main thread spawns to a new one in MyWebService.GetDataAsync();, but since the main thread awaits there, it waits on the result in GetDataAsync().Result. Meanwhile, say the data is ready. Why doesn't the main thread continue it's continuation logic and returns a string result from GetDataAsync() ?
Can someone please explain me why there is a deadlock in the above example? I'm completely clueless about what the problem is ...