在引发所有事件(或组合事件)后,C#做一些工作

时间:2013-08-26 07:36:41

标签: c# events

我想订阅在引发所有其他多个事件时将引发的事件。

假设我有多个任务(A)要先做(例如动画多个独立视图),我也可以订阅任务完成的事件,我还想做其他一些工作所有这些事件结束后(B)。

第一个任务的数量(A)每次都会有所不同,所以目前我设置一个计数器来处理任务数A,订阅N个事件,并在事件处理程序中为任务完成我递减计数器,当它为零时,我执行任务B.

是否有更好的方法来组合这些事件而不是使用计数器?

2 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,那么当你启动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 ......”)。

但是,您可以通过Task.Run的{​​{1}}事件通过以下扩展方法创建任务,而不是通过Completed创建任务:

Storyboard

请注意,此方法会创建一个在故事板的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()); 基本上安排继续任务在UI线程上运行(如果你要访问UI元素,这是必需的。)

答案 1 :(得分:0)

我会为每个事件设置一个标识符(例如,基于枚举),然后将您希望调用的所有事件添加到列表中。每当执行事件时,我都会将其从列表中删除。

在每个事件中,您调用的方法只有在列表为空时才会实际执行任何操作。