簡體   English   中英

等待一個任務(或多個任務)達到某個里程碑,async/await 方式

[英]Wait for a task (or tasks) to reach certain milestone, the async/await way

有很多關於如何等待線程退出的示例,但有時我需要等到幾個線程“准備好”或達到某個里程碑。

閱讀后: 等待 .NET 線程啟動的正確方法是什么?

http://www.albahari.com/threading/

如果我理解正確:

等待一個子任務准備好

//Main Method
var wh = new AutoResetEvent(false);
Task childTask = Task.Run(() => ChildTask(wh);
wh.WaitOne();

//Child
private void ChildTask(Barrier barrier){
//do what is needed to be done before main thread continues...
wh.Set();

}

等待幾個孩子准備好

//Main Method
var barrier = new Barrier(N+1);
Task childTask = Task.Run(() => ChildTask1(barrier);
Task childTask = Task.Run(() => ChildTask2(barrier);
...
Task childTask = Task.Run(() => ChildTaskN(barrier);

barrier.SignalAndWait(); //When all childs signal "ready" i will continue
OnMyEvent(); //for example, trigger an event

//Every Child
private void Child_i(Barrier barrier){
mainTask.MyEvent += MyEventHandler; //complete subscription before going any further
//do what is needed to be done before main thread continues...
barrier.SignalAndWait();

}

(請隨意添加或建議其他好的模式)

所以我的問題是:是否可以使用 async/await 模式來實現相同的目標?

使用這種新模式有什么優點/缺點嗎?

您可以使用await Task.WhenAllTask.WaitAll來等待您的任務完成。 如果你想等待一個任務到達某個里程碑,你可以將它拆分為 2 個任務並使用ContinueWith ,例如:

var task1 = Task.Run(() => Task1Part1());
task1.ContinueWith(t => Task1Part2(t.Result));
var task2 = Task.Run(() => Task2Part1());
task2.ContinueWith(t => Task2Part2(t.Result));

await Task.WhenAll(task1, task2);

重構您的示例,您無需使用BarrierAutoResetEvent等即可獲得相同的結果:

Task.WaitAll(
    Task.Run(() => ChildTask1()),
    Task.Run(() => ChildTask2()),
    Task.Run(() => ChildTask3()));

或者稍微干凈一點

Parallel.Invoke(
    () => ChildTask1(),
    () => ChildTask2(),
    () => ChildTask3());

這些方法的問題是它們仍然會阻塞前台線程,直到所有子任務都完成。 如果您想使用 async await 模式,那么您的子任務將需要是異步的,並且您從中調用它們的上下文也將是異步的。 結果可能是這樣的

public async Task PerformChildTasksAsync()
{
    ...

    await Task.WhenAll(
        ChildTask1Async(),
        ChildTask2Async(),
        ChildTask3Async());

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM