例如,以下代碼手動實體化一個 Task 并傳遞給 aTask.WhenAll中的 aList<T>
public async Task Do3()
{
var task1 = new Task(async () => { await Task.Delay(2000); Console.WriteLine("########## task1"); });
var taskList = new List<Task>() { task1};
taskList[0].Start();
var taskDone = Task.WhenAll(taskList);
await taskDone;
}
不啟動任務就行不通,它會永遠掛起從控制臺應用程式呼叫,但下面的作業沒有啟動就可以了
public async Task Do3()
{
//var task1 = new Task(async () => { await Task.Delay(2000); Console.WriteLine("########## task1"); });
var taskList = new List<Task>() { SubDo1() };
//taskList[0].Start();
var taskDone = Task.WhenAll(taskList);
await taskDone;
}
public async Task SubDo1()
{
await Task.Delay(2000);
Console.WriteLine("########## task1");
}
uj5u.com熱心網友回復:
Task在這里以兩種完全不同的方式使用;當你呼叫一個async方法時:你是自己開始的;此時,可能會發生兩件事:
- 它可以運行到完成(最終)而不會達到真正的異步狀態,并將已完成(或錯誤)的任務回傳給呼叫者
- 它可以到達一個不完整的可等待物件(在這種情況下
await Task.Delay),此時它會創建一個表示當前位置的狀態機,在該不完整的可等待物件上安排完成操作(執行接下來發生的任何事情),然后將一個不完整的任務回傳給呼叫者
它不是“未開始”;將任何東西回傳給呼叫者:我們已經開始了。但是,與 不同的是Task.Start(),我們在當前執行緒(而不是外部作業執行緒)上開始這項作業,其他執行緒僅根據不完整的可等待物件如何安排編譯器提供的完成回呼來參與。
這與最初什么都不啟動的場景非常不同new Task(...)。這就是為什么他們的行為不同。還要注意這里Task建構式的備注部分- 它是一個非常小眾的 API,老實說:不是非常推薦。
另外:當您不立即await使用async方法時,您實際上進入了并發領域(假設可等待物件并不總是同步完成)。在某些情況下,這很重要,并且可能會導致執行緒問題重新競爭條件。不過,在這種情況下應該沒什么關系。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318773.html
