[英]Async/Await or Task.Run in Console Application/Windows Service
[英]await Task.Run(…) behaving differently for console and windows application
我有一個帶有以下代碼的控制台應用程序
static void Main(string[] args) {
Method();
Console.ReadKey();
}
private static void Method() {
Task t = DoSomething();
t.Wait();
Console.WriteLine("Finished");
}
private static async Task DoSomething() {
await Task.Run(() =>
Thread.Sleep(1000));
}
一切都按我的預期工作,並且運行該程序一秒鍾后控制台顯示“ Finished”。 當我將相同的代碼移到Windows應用程序中時,我發現該程序只是停止了
private void button1_Click(object sender, EventArgs e) {
Task t = DoSomething();
t.Wait();
MessageBox.Show("Finished");
}
private static async Task DoSomething() {
await Task.Run(() =>
Thread.Sleep(1000));
}
調試器顯示當前執行行是t.Wait(),即使已運行DoSomething方法中的Task。
在Windows應用程序中我有什么需要做的,而在控制台應用程序中我不需要做的嗎? 還是我從根本上誤會了什么?
這是經常發生的事情。 您正在造成僵局。
簡而言之,諸如WinForms和WPF之類的框架“強制”了線程同步上下文,這意味着每當啟動新任務時,其余代碼將在啟動時在同一線程上繼續。 這樣做是為了確保,例如,在任務返回后,在UI線程上啟動的代碼將繼續在同一線程上運行。
因為您正在阻塞任務(使用Wait
方法),並且任務試圖將值返回到該阻塞線程,所以兩個線程都進入死鎖狀態。
在控制台應用程序中不會發生此行為,因為沒有強制執行線程同步上下文,因此任務的延續可以在完全不同的第三個線程上運行。
Stephen Cleary在這里對此進行了很好的解釋: http : //blog.stephencleary.com/2012/07/dont-block-on-async-code.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.