這兩者非常相似。遇到async
方法時,C#編譯器將生成一個狀態機,以便返回的Task
表示方法的完成。由於您的方法所做的唯一工作是等待另一個異步操作,因此這在功能上幾乎等同於直接從內部異步操作返回Task
。
然而,關於如何拋出同步部分的異常有一個細微的區別。在async
方法中執行的任何邏輯包括該方法開始處的同步部分(在第一個await
語句之前)將被編譯爲異步操作的一部分。這意味着,前提例外將不再同步發送,而是通過異步返回Task
:
private static async Task FirstDelayAsync()
{
if (StateNotValid)
throw new NotSupportedException();
await Task.Delay(1000);
}
private static Task SecondDelayAsync()
{
if (StateNotValid)
throw new NotSupportedException();
return Task.Delay(1000);
}
測試了上面的代碼:
var t1 = FirstDelayAsync();
await t1; // exception thrown here
var t2 = SecondDelayAsync(); // exception thrown here
await t2;
,如果你等待這不會有所作爲您在您稱之爲同一行的異步操作。但是,如果你推遲等待,這會有所作爲;例如,如果您同時推出幾個異步操作,然後等待他們使用Task.WhenAll
在一起:
var tasks = Enumerable
.Range(0, 10)
.Select(i => ProcessAsync(i))
.ToArray();
await Task.WhenAll(tasks);
在上面的代碼中,從ProcessAsync
調用拋出同步異常會阻止甚至正在啓動的後續異步操作,因爲異常立即停止枚舉。這通常適用於應該停止整個過程的失敗前提條件。
更新:另一個重要的不同之處在於使用await
沒有ConfigureAwait(false)
將會使你的代碼更容易死鎖。見this answer。
一個叫做'First',另一個叫'Second'。一個是「異步」,另一個不是。這不是http://puzzling.stackexchange.com。你真的想知道什麼?你的問題[如何異步調用同步方法](http://stackoverflow.com/questions/18830397/awaiting-a-non-async-method)? – CodeCaster
@CodeCaster:這是一個合理的問題。即使兩者之間沒有功能上的差異(事實並非如此),OP的要求也是合理的。但是,這可能是一個重複的問題。 – Douglas
爲了DRY的利益標記爲重複。儘管它的標題,鏈接的問題和它接受的答案主要討論'Task.Delay'的情況,而不是'Task.Run'。 – Douglas