Pregunta

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?

¿Fue útil?

Solución

As a general rule, synchronous wrappers around asynchronous methods are strongly discouraged. When you use the Result approach, you run the risk of deadlock (as I describe on my blog); also, Result will 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 the await which checks whether the task is already complete. So it's possible that performance improvements in the official Microsoft.Bcl.Async are causing the difference in behavior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top