[英]What is the difference between these following async methods?
在理解異步原理時,我實際上遇到了一些問題。 有人可以告訴我以下代碼示例之間的區別嗎? 如果有人認為這個例子是完全錯誤的,這個家伙可以給我糾正嗎?
所以這是我的代碼:
private async void DoHardStuffAsync()
{
var result = DoHardStuff();
var secondResult = DoHardStuff();
var thirdResult = DoHardStuff();
await Task.WhenAll(result, secondResult, thirdResult);
MessageBox.Show(result.Result + secondResult.Result + thirdResult.Result);
}
private Task<string> DoHardStuff()
{
return Task.Run(() =>
{
var time = DateTime.Now;
while (DateTime.Now.Subtract(time).Milliseconds < 900)
{ }
return "finished";
});
}
和這個:
private async void DoHardStuffAsync()
{
var result = DoHardStuff();
var secondResult = DoHardStuff();
var thirdResult = DoHardStuff();
MessageBox.Show(await result + await secondResult + await thirdResult);
}
為什么異步!=並行? 對於什么我應該使用異步,對於什么我應該使用並行(例如任務,線程)?
並行和異步是兩種不同的並發形式。 並行使用多個線程(例如,用於CPU綁定代碼)。 異步使用多個操作,但不一定使用多個線程(例如,用於I / O綁定代碼)。
Task.Run
是這兩個世界之間的橋梁。 它啟動(可能是受CPU限制)在后台線程上運行的代碼,並返回一個任務,該任務允許調用線程異步處理該工作。
雖然Task.Run
對於基本並行性Task.Run
是可以的,但是如果您有真正的CPU約束工作要做,那么最好使用Parallel
或Parallel LINQ。
關於您的代碼示例,它們都非常相似:啟動了三個后台任務,並且調用線程異步等待它們全部完成。
第一個確實調用了Task<T>.Result
,我不建議這樣做,因為如果存在某些異常,則Result
將異常包裝在AggregateException
而await
直接引發異常。 AggregateException
使錯誤處理變得復雜。
第二個任務分別await
每個任務,雖然可以,但是IMO並不理想。 我認為await Task.WhenAll(..)
方法具有更清晰的意圖(而且效率也await Task.WhenAll(..)
一點)。
因此,我建議結合使用以下方法:
private async Task DoHardStuffAsync()
{
var result = DoHardStuff();
var secondResult = DoHardStuff();
var thirdResult = DoHardStuff();
await Task.WhenAll(result, secondResult, thirdResult);
MessageBox.Show(await result + await secondResult + await thirdResult);
}
我還將返回類型更改為Task
。 通常,應避免使用async void
,正如我在MSDN文章中所述。
DoHardStuff
的實現也有問題。 通常,應該使用Task.Run
來調用方法,而不是作為方法的實現 。 我有一篇博客文章 ,詳細介紹了這個主題。
這些方法出於實用性原因而相似。 但是,我認為您對Task.Result的調用在不同之處。 這假定操作已完成並獲得任務的結果。 這樣做非常危險,並且由於它可能會炸毀,因此最好使用await 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.