【问题标题】:C# do some work after all events are raised (or combine events)在引发所有事件(或组合事件)后,C# 做一些工作
【发布时间】:2013-08-26 07:36:40
【问题描述】:

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

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

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

有没有比使用计数器更好的方法来组合这些事件?

【问题讨论】:

  • 最后一个事件 A 可以标记为最后一个,例如使用布尔字段或其他东西。然后如果它是真的,你射击 B。
  • 我建议你看看 Rx Extensions,必须有一些东西可以轻松可靠地管理事件链和传播。

标签: c# events


【解决方案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...”)。

但是,您可以通过 StoryboardCompleted 事件通过以下扩展方法创建任务,而不是通过 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 元素,则需要这样做)。

【讨论】:

  • 问题是我正在使用 WPF 用户控件及其动画来执行“任务”,我不确定我是否可以在这里使用 .net Tasks。或者我可以吗?
  • 您可以但可能不能通过Task.Run,正如我所提到的。您可以从 Storyboard.Completed 事件中获取任务(请参阅编辑)。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多