假设我想要快速地将以下方法异步运行:
ResultType SynchronousCode(ParamType x)
{
return SomeLongRunningWebRequest(x);
}
以下两个代码示例的执行/调度方式有何区别?
async Task<ResultType> AsynchronousCode(ParamType x)
{
return await Task.Run(() => SomeLongRunningWebRequest(x));
}
与之相比:
async Task<ResultType> AsynchronousCode(ParamType x)
{
await Task.Yield();
return SomeLongRunningWebRequest(x);
}
我理解Task.Yield()的调用将确保线程立即返回给调用者,而Task.Run()肯定会在ThreadPool上安排代码运行,但这两种方法是否有效地使方法异步?假设我们在默认的SynchronizationContext上。
Task.Yield()
更糟糕,因为你知道它将在后台线程上运行,而另一种方法只有在正确调用时才会在后台线程上运行。两种选项都不好的原因是为同步函数创建异步包装器本来就是反模式,你不应该这样做。如果调用者需要,请让其调用SynchronousCode
上的Task.Run()
。 - Scott Chamberlain