让我们假设我有两种方法,比如......
public void MyMethod()
{
// do some stuff
}
public Task MyMethodAsync()
{
//run MyMethod asynchronously
}
以异步方式执行它的最佳形式是什么?
喜欢这个
public Task MyMethodAsync()
{
return Task.Run(() => MyMethod());
}
还是喜欢这个?
public async Task MyMethodAsync()
{
await Task.Run(() => MyMethod());
}
答案 0 :(得分:3)
您应该在何时使用Task.Run
时阅读Stephen Cleary's tutorial。
简短回答:不要使用Task.Run
来创建虚假的异步方法。如果您的代码不是真正的异步,那么让调用者决定是否应使用线程(或其他)来调用您的代码。
答案 1 :(得分:1)
最好还是走另一条路。将内部任务构建为异步,然后让所有不能使用异步方法的调用者在内部使用异步,并等待它。
public void MyMethod()
{
MyMethodAsync().Wait();
}
public async Task MyMethodAsync()
{
// do some stuff
}
你的两种方法都没有真正做出任何异步。异步不是关于在后台运行某些东西,这是任务库(或并行扩展,或线程等)的领域。 Async是关于能够在没有更好的事情的情况下为多个事情重用单个线程 - 这使事情更具可扩展性。制作伪异步方法只是隐藏了一个事实,即您正在使用新线程而不是重用相同的线程,这使得系统LESS可扩展。
为了做到这一点,真正的异步进程需要从内到外编写。一切(或至少是耗时的部分)需要依赖于那样做的异步方法。例如,在等待调用返回,数据库调用或文件I / O时,进行SOAP调用,其中线程基本上处于空闲状态。 Async允许该线程执行其他有用的操作而不是闲置。
答案 2 :(得分:1)
对于第一种方法,您也可以在单独的线程上执行任务。它并不是真正的异步,因为你没有明确地等待线程结束以启动新进程。如果你打电话给它,它将在任务完成之前继续。
public Task MyMethodAsync()
{
return Task.Run(() => MyMethod());
}
看第二个版本。您正在等待任务完成,以便您可以在不占用当前线程的情况下执行某些操作。
public async Task MyMethodAsync()
{
await Task.Run(() => MyMethod());
DoMoreWork();
//Do something following the completion of the task
//without binding up the calling thread, but actually complete it on that thread.
}