簡體   English   中英

這些以下異步方法之間有什么區別?

[英]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將異常包裝在AggregateExceptionawait直接引發異常。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM