C# 中await前后執行線程的問題


  懸賞園豆:20 [已解決問題] 瀏覽: 1763次 解決於 2018-08-15 22:43 

今天有點疑惑就寫了個測試的代碼,發現控制台和Winform中不一樣

比如:

控制台:

...Main(){  Test(); }

private static async void Test()
{
Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); Show("Test.Task"); });
Show("Test.After");//輸出字符串和當前線程
}

private static void Show(string str)
{
Console.WriteLine($"{str}:{Thread.CurrentThread.ManagedThreadId}\r\n");
}

輸出:

Test.Before:1

Test.Task:3

Test.After:3

 

Winform中:

...test(){ Test(); }

private async void Test()

{

Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); });
Show("Test.After");//輸出字符串和當前線程

}

public void Show(string str)
{
richTextBox1.AppendText($"{str}:{Thread.CurrentThread.ManagedThreadId}\r\n");
}

輸出:

Test.Before:1

Test.After:1

 

為什么這兩個不一樣呢?新手求解答

JoySn的主頁 JoySn  初學一級 | 園豆:138
提問於:2018-08-15 20:21
 
最佳答案
-1

對於當前運行的winform程序,始終只有一個UI線程

收獲園豆: 20
回復  dudu 高人七級 |園豆:38806 | 2018-08-15 20:46

那在控制台中,Task.Run里不是開了一個子線程3嗎?await結束后也是3執行的。主要是疑惑為什么控制台中await結束后線程不是1,而是子線程3

支持(0) 反對(0) 回復 JoySn | 園豆:138 (初學一級) | 2018-08-15 20:48

@JoySn: 控制台程序沒有主線程,程序跟着線程跑,啟動線程3,就在一直在線程3里跑,除非再創建新的線程

支持(0) 反對(0) 回復 dudu | 園豆:38806 (高人七級) | 2018-08-15 20:57

@JoySn: 所以在控制台程序中同步方法中調用異步方法不會發生死鎖

支持(0) 反對(0) 回復 dudu | 園豆:38806 (高人七級) | 2018-08-15 21:01
其他回答(2)
0

因為調用 Task 的 Run 之后返回的是 Task 在等待 Task 的時候可以設置 ConfigWait() 參數,通過這個參數可以設置之后是否返回主線程。

 

在控制台使用的時候,因為控制台沒有 dispatcher 調度,所以在執行 Task 的run 等待就會發現當前的調度就是 Task 所在的線程,所以在控制台就是在創建 Task 的線程

 

在 WinForm 因為有主線程,所以從 Task 的 run 方法可以回到主線程

 

Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); }).ConfigureAwait(true);
Show("Test.After");

Test.Before:1

Test.After:1

 

Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); }).ConfigureAwait(false);
Show("Test.After");

 

Test.Before:1

Test.After:3


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM