[英]Why the async await not working as expected
我正在從教程中學習TPL(異步/等待),並嘗試使用控制台應用程序對其進行測試。 請不要被我的無知所冒犯。 我確定我在某處做錯了-我編寫了以下代碼:
static void Main(string[] args_)
{
Task<int> task = ProcessNumber(25);
Console.WriteLine(string.Format("{0}: Waiting started...", DateTime.Now));
task.Wait();
Console.WriteLine(string.Format("{0}: Waiting ended...", DateTime.Now));
Console.WriteLine(task.Result);
Console.WriteLine("Press any key to terminate!");
Console.ReadLine();
}
static async Task<int> ProcessNumber(int i_)
{
Thread.Sleep(1000);
var integer = await IncrementNumber(i_ * 23);
return integer;
}
static async Task<int> IncrementNumber(int j_)
{
Thread.Sleep(6000);
return (j_ + 23) / 23;
}
這是純C#控制台代碼。 我的問題是為什么我得到以下輸出:
3/5/2015 5:22:37 PM: Waiting started...
3/5/2015 5:22:37 PM: Waiting ended...
26
“等待開始”和“等待結束”之間是否應該有相當長的時間間隔?
更新
在回答之后,我發現Task.Delay(..)和Thread.Sleep(..)是不一樣的,因為它們的工作方式非常不同。 這是一個很好的鏈接 ,並舉例說明。
似乎將TPL視為另一種多線程框架是錯誤的。 所有的答案對我都有幫助,所以我投了贊成票。 但是,我選擇了喬恩的答案,因為這是最具說明性的,也是第一個出現的答案。 謝謝大家!
否,因為實際上您在打印“ Waiting started
之前要睡眠7秒鍾。 這是發生了什么:
如果將每個Thread.Sleep
更改為
await Task.Delay(...);
然后您將看到您的期望。 新流程將是:
真正重要的是要理解,直到異步方法在實際上需要暫停的第一個await
發生(因為等待狀態尚未完成)之前,它才同步執行。 這不像調用異步方法將其拆分為另一個線程一樣。
這是因為您的方法都不是異步的。 它們通過返回Task
來偽裝成異步的,但是它們都是同步執行的。
實際上,您應該收到針對IncrementNumber
號的編譯器警告,說明此異步方法缺少'await'運算符,並且將同步運行...等 。 它基本上說您的方法將同步執行。 這個答案詳細解釋了 。
因此,當ProcessNumber
返回時,整個嵌套方法調用已經同步完成。
更改方法以使用await Task.Delay
而不是Thread.Sleep
使其異步。
您需要重構代碼。 像這樣
static async Task<int> IncrementNumber(int j_)
{
await Task.Delay(...);
return (j_ + 23) / 23;
}
如果找到CPU綁定任務而不是Thread.Sleep,則需要執行以下操作。
//it will create a new thread then sleep. await Task.Run( () => ( CPUBoundTask()); var integer = await IncrementNumber(i_ * 23); return integer;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.