我想了解異步編程好一點的基礎,所以我創建了下面的代碼片段:爲什麼Task.Wait()的行爲與Console.WriteLine()無關?
private void TaskContinuations()
{
// Task for counting prime numbers
Task<int> primeNumberTask = Task.Run(() =>
Enumerable.Range(2, 3000000)
.Count(n =>
Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
.All(i => n % i > 0)));
var awaiter = primeNumberTask.GetAwaiter();
// primeNumberTask.Wait(); // Option 1: Waiting but not printing (rather unexpected here)
awaiter.OnCompleted(() =>
{
var result = awaiter.GetResult();
Console.WriteLine(result);
});
//primeNumberTask.Wait(); // Option 2: Waiting but not printing (kind of expected here)
Console.Read(); // Option 3: Works and prints as expected
}
我明白,我必須防止主UI任務從停止,以防止後臺任務從被終止。因此,Console.Read();
會阻止UI線程,並且如果在素數編號任務完成之前未按某個鍵,則控制檯中的輸出正確爲216816
。所有清除,直到這裏。
所以我認爲調用Wait();
會產生同樣的效果(至少在OnCompleted
回調之前調用),因爲主UI任務會阻塞並等待質數任務完成。這確實發生了,但是在這兩種情況下(選項1和選項2),主線程都會等待,然後終止而不輸出任何結果。
這是爲什麼?我的行爲的期望是以下(這可能是掉了一點,所以我的問題)
- 主UI線程等待/爲任務阻塞,直到它完成,訂閱完成的任務,所以執行回調立即,輸出打印是
216816
。但那不會發生!
或
- 主UI線程等待/塊,並且當任務完成它執行
OnCompleted
之前立即如此做。所以這裏沒有產出。
那麼我在這裏想念什麼,有人可以對我點燈?
當您取消註釋'primeNumberTask.Wait();'時,是否還有'Console.Read();'。如果你不這樣做 - 程序已經返回了,它有機會輸出任何東西。 – zerkms
[相關](http://stackoverflow.com/a/33310175/335858) – dasblinkenlight
沒有,如果我保持Console.Read();它確實在所有情況下打印'216816'。給出的選項是'exclusive';-) – Anytoe