Lia*_*iam 11 c# multithreading asynchronous task-parallel-library async-await
我最近遇到了这个由我们为我们工作的承包商编写的代码.它要么是非常聪明或愚蠢(我认为后者,但我想要第二个意见).我没有大规模的速度async await.
基本上它的工作方式如下:
public bool Send(TemplatedMessageDto message)
{
return Task.Run(() => SendAsync(message))
.GetAwaiter()
.GetResult();
}
public async Task<bool> SendAsync(TemplatedMessageDto message)
{
//code doing stuff
var results = await _externalresource.DothingsExternally();
//code doing stuff
}
Run Code Online (Sandbox Code Playgroud)
据我所知,首先Task.Run()是无意义和低效的?应该是:
public bool Send(TemplatedMessageDto message)
{
return SendAsync(message))
.GetAwaiter()
.GetResult();
}
public async Task<bool> SendAsync(TemplatedMessageDto message)
{
//code doing stuff
var results = await _externalresource.DothingsExternally();
//code doing stuff
}
Run Code Online (Sandbox Code Playgroud)
我也不相信这实际上是一种异步方法,因为它仍然会等待,对吧?我认为唯一的优势(甚至是重写)就是释放主要的工作者线程.
有人可以确认第一个任务不应该存在吗?
我也不相信这实际上是一种异步方法,因为它仍然会等待,对吧?
正如Yuval解释的那样,它不是.您不应该使用异步同步.
据我所知,首先
Task.Run()是无意义和低效的?
不是真的,Task.Run以这种方式使用是有价值的.
由于您在异步方法上阻塞(您不应该这样做),因此您可能会陷入僵局.这种情况发生在UI应用程序和asp.net中SynchronizationContext.
使用Task.Run清除,SynchronizationContext因为它将工作卸载到ThreadPool线程并消除死锁的风险.
因此,阻塞是不好的,但如果你最终使用Task.Run更安全.
我也不相信这实际上是一种异步方法,因为它仍然会等待,对吧?
您的承包商所做的是使用异步反模式同步.他可能这样做是为了避免创建一个同步完成其工作的附加方法.他不必要地使用调用Task.Run并立即阻止它GetResult.
使用GetAwaiter().GetResult()将传播内部异常,如果发生这种情况,而不是包装AggregateException.
我认为唯一的优势(甚至是重写)就是释放主要的工作者线程.
您的版本和他的将在执行时阻止主线程,而他的也将通过使用线程池线程来执行此操作.正如Bar所提到的,这可以帮助避免与同步上下文编组有关的问题的死锁.如果需要,我建议创建一个同步等效项.