I'm currently trying to make a piece of code written in VS 2012, using Microsoft.Bcl.Async and .NET 4.0, work in VS 2010. For VS 2010 I've installed the Async CTP (ver. 3), such that I am able to compile my project written in V S2012.
After quite a lot of trouble getting the Async CTP pack to work, I am now able to compile my project under both VS 2012 as well as VS 2010.
However, I'm seeing some differences in how the code works in run-time. The code I am exercising is shown below:
public class Fetcher
{
public string RunTask()
{
Task<string> task = TaskEx.Run(() => RunTaskAsync());
return task.Result;
}
public async Task<string> RunTaskAsync()
{
await TaskEx.Delay(1);
return "Hello";
}
}
Basically, what I have is an async method, for which I need to have a sync wrapper around, such that clients can call either the async or sync version of the method.
The problem: When running the code from VS 2012 both method will return the result "Hello", and more importantly, both methods will exit properly. Running the code from VS 2010, however, is a far different story. The async method works as intended, but the sync wrapper method simply hangs, and the result is never produced.
Since I am fairly new to the concept of TPL and async/wait, I'm having some trouble explaining the behavior I am seeing here. Is there some sort of limitations in the Async CTP that kicks in, that I am not aware of, or am I doing this in a conceptually wrong way?
As a general rule, synchronous wrappers around asynchronous methods are strongly discouraged. When you use the
Resultapproach, you run the risk of deadlock (as I describe on my blog); also,Resultwill wrap any exceptions, which makes your error handling much trickier.So I'd say "don't do that."
As far as the Async CTP goes, there are a number of bugs that are known to exist (plus several more that are not public). And they're not going to be fixed. I strongly recommend upgrading everyone to VS2012.
For this particular issue, it may be performance-related. E.g.,
Task.Delay(1)returns a task that will complete almost immediately, so there's a race condition between starting the delay and theawaitwhich checks whether the task is already complete. So it's possible that performance improvements in the officialMicrosoft.Bcl.Asyncare causing the difference in behavior.