我目前正在尝试使用Microsoft.Bcl.Async和.NET 4.0在VS 2012中编写一段代码,在VS 2010中工作。对于VS 2010,我安装了Async CTP(版本3) ,这样我就可以编译用V S2012编写的项目。
使Async CTP包运行起来非常麻烦,我现在能够在VS 2012和VS 2010下编译我的项目。
但是,我发现代码在运行时的工作方式存在一些差异。我正在行使的代码如下所示:
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";
}
}
基本上,我所拥有的是异步方法,我需要有一个同步包装器,这样客户端就可以调用该方法的异步或同步版本。
问题:从VS 2012运行代码时,两种方法都会返回结果“Hello”,更重要的是,两种方法都会正常退出。然而,从VS 2010运行代码是一个完全不同的故事。异步方法按预期工作,但同步包装器方法只是挂起,结果永远不会产生。
由于我对TPL和异步/等待的概念相当新,我在解释我在这里看到的行为时遇到了一些麻烦。 Async CTP中是否存在某些限制,我不知道,或者我是否以概念错误的方式执行此操作?
答案 0 :(得分:4)
作为一般规则,synchronous wrappers around asynchronous methods are strongly discouraged。当您使用Result
方法时,run the risk of deadlock(正如我在博客中描述的那样);此外,Result
将包装任何异常,这使您的错误处理更加棘手。
所以我会说“不要那样做。”
就Async CTP而言,已知存在许多错误(还有一些不公开的错误)。他们不会被修复。我强烈建议将所有人升级到VS2012。
对于这个特定问题,它可能与性能有关。例如,Task.Delay(1)
返回一个几乎立即完成的任务,因此在启动延迟和await
之间存在竞争条件,检查任务是否已经完成。因此,官方Microsoft.Bcl.Async
中的性能改进可能会导致行为上的差异。