如果我正确理解了这个问题,您可以在启动 A 任务时增加一个计数器,并在完成每个任务时减少事件处理程序中的计数器。同样在事件处理程序中,您检查(在减少计数器之后)计数器是否为零。如果是这样,你做任务 B。
我建议您查看Tasks(又名“任务并行库 (TPL)”),它允许您执行以下操作:
Task.WhenAll( new Task[] {
Task.Run(()=> { //... do work A1... },
Task.Run(()=> { //... do work A2... },
Task.Run(()=> { //... do work A3... }})
.ContinueWith(()=> {//... do work B... });
更新:根据您在下面的评论中提到的 WPF 动画,Task.Run 可能不适合这里。如果我没记错的话,你会得到一个Completed 事件,并且没有办法在代码中同步运行动画(如“...做A1...”)。
但是,您可以通过 Storyboard 的 Completed 事件通过以下扩展方法创建任务,而不是通过 Task.Run 创建任务:
public static Task<Storyboard> BeginAsync(this Storyboard sb)
{
var tcs = new TaskCompletionSource<Storyboard>();
sb.Completed += (s, a) => tcs.TrySetResult(sb);
sb.Begin();
return tcs.Task;
}
请注意,此方法创建一个任务,该任务在情节提要的Completed 事件处理程序中完成,并在返回任务之前开始情节提要动画。另请注意,您可以为其他类型和事件编写类似的扩展方法。
您可以使用这种方法,例如:
var sb1 = (Storyboard)mainWindow.FindResource("Storyboard1");
var sb2 = (Storyboard)mainWindow.FindResource("Storyboard2");
var sb3 = (Storyboard)mainWindow.FindResource("Storyboard3");
Task.WhenAll( new Task[] {
sb1.BeginAsync(),
sb2.BeginAsync(),
sb3.BeginAsync() })
.ContinueWith(() => MessageBox.Show("All done!"),
TaskScheduler.FromCurrentSynchronizationContext());
TaskScheduler.FromCurrentSynchronizationContext() 基本上将延续任务安排在 UI 线程上运行(如果您要访问 UI 元素,则需要这样做)。