好的,所以,第二個是簡單的,所以讓我們來處理那個。
對於第二項任務t2
,您不會對Task.Delay(1000)
的結果做任何事情。你不是await
它,你不是Wait
它等等。鑑於方法不是async
我想你的意思是它是一個阻塞等待。要做到這一點,您希望將Wait()
添加到Delay
調用的末尾,以使其成爲阻止等待,或者僅使用Thread.Sleep()
。
對於第一個任務,你被一個事實,即你使用var
咬傷。這是更清晰的發生了什麼,當你不使用var
:
Task<Task<int>> t1 = Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
});
你回不只是int
的Task
的int
任務的任務。內部任務完成後,外部任務將「完成」。當您使用WhenAll
時,您不關心外部任務何時完成,您關心何時完成任務內部任務完成。有很多方法可以解決這個問題。一種是使用Unwrap
。
Task<int> t1 = Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
}).Unwrap();
現在,你有你的預期Task<int>
和WhenAll
將需要至少2000毫秒,符合市場預期。你也可以添加在另一個await
調用做同樣的事情:
Task<int> t1 = await Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
});
正如svick in a comment提到的另一種選擇是隻用Task.Run
,而不是StartNew
。 Task.Run
具有該採取Func<Task<T>>
並返回Task<T>
,並自動解開他們爲你的方法一組特殊的重載:
Task<int> t1 = Task.Run(async() =>
{
await Task.Delay(2000);
return 2;
});
出於這個原因,它是最好使用Task.Run
爲默認選項,當你創建異步lambda表達式因爲它會爲您「處理」這個問題,但最好在無法使用Task.Run
的複雜案例中瞭解它。
最後我們來看看你沒有做的選擇,這是你在這種情況下應該實際做的。由於Task.Delay
已經返回一個任務,因此無需首先將其放入StartNew
。而不是創建一個嵌套的任務和使用Unwrap
你只是沒有在第一時間把它包:
var t3 = Task.Delay(3000);
await Task.WhenAll(t1, t2, t3);
如果你真的只是想等待這是你應該做的事情的固定時間量。
@GrantThomas我想分配給一個變量,但它給了我一個編譯器錯誤,我該怎麼做? – MuriloKunze
@MuriloKunze爲了回答這個問題,我們需要看到代碼行和錯誤。 – Servy
我試過這個:var taskresult = await Task.WhenAll(t1,t2); 但它給了我一個'不能分配void的隱式類型局部變量'。 – MuriloKunze