C# 等待一个或多个任务达到某个里程碑,即异步/等待方式

C# 等待一个或多个任务达到某个里程碑,即异步/等待方式,c#,multithreading,asynchronous,synchronization,async-await,C#,Multithreading,Asynchronous,Synchronization,Async Await,关于如何等待线程退出的例子有很多,但有时我需要等待几个线程“准备就绪”或达到某个里程碑 阅读后: 及 如果我理解正确: 等待一个子任务准备就绪: //Main Method var wh = new AutoResetEvent(false); Task childTask = Task.Run(() => ChildTask(wh); wh.WaitOne(); //Child private void ChildTask(Barrier barrier){ //do what i

关于如何等待线程退出的例子有很多,但有时我需要等待几个线程“准备就绪”或达到某个里程碑

阅读后:

如果我理解正确:

等待一个子任务准备就绪:

//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();

}
等待几个孩子准备好:

//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模式来实现相同的功能


使用这种新模式有什么优点/缺点吗?

您可以使用
等待任务。whalll
任务。WaitAll
等待任务完成。 如果要等待某个任务达到某个里程碑,可以将其分成两个任务,并使用
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);

重构您的示例,您可以实现相同的结果,而无需使用
屏障
自动恢复事件
等:

Task.WaitAll(
    Task.Run(() => ChildTask1()),
    Task.Run(() => ChildTask2()),
    Task.Run(() => ChildTask3()));
或者稍微干净一点

Parallel.Invoke(
    () => ChildTask1(),
    () => ChildTask2(),
    () => ChildTask3());
这些方法的问题是,在所有子任务完成之前,它们仍然会阻止前台线程。如果您想使用AsyncWait模式,那么您的子任务将需要是异步的,并且您从中调用它们的上下文也将是异步的。结果可能是

public async Task PerformChildTasksAsync()
{
    ...

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

    ...
}

等待任务。当所有(任务)
您可以使用Stephen Toub的,它是为异步使用而设计的。我会检查它,谢谢您的建议。这样任务可以在到达te里程碑时继续。有了障碍,所有任务都必须等待“慢加入者”。分而治之:)