用于等待事件处理程序的AsyncEx DeferralManager

时间:2014-11-14 18:09:23

标签: c# async-await

我有thread中提到的类似问题,根据Stephen Cleary的评论,WinRT的解决方案是使用延期。线程中指出的解决方案也适用于我,但我想尝试使用延迟,因为它可能是或成为处理这种情况的标准方法。

所以我读了他的blog并尝试将其应用到我的代码中,但我似乎无法让它工作。发生的事情是仍然没有等待事件订阅。我也找不到任何可以运行和分析的完整示例程序。所以我尝试创建一个示例控制台程序来演示我所看到的问题。

首先,我有事件处理程序委托和事件参数定义:

public delegate void CancelEventHandlerAsync(object sender, CancelEventArgsAsync e);

public class CancelEventArgsAsync : CancelEventArgs
{
    private readonly DeferralManager _deferrals = new DeferralManager();

    public IDisposable GetDeferral()
    {
        return this._deferrals.GetDeferral();
    }

    public Task WaitForDefferalsAsync()
    {
        return this._deferrals.SignalAndWaitAsync();
    }
}

然后是作为事件发送者的子模块定义:

public class ChildModule1
{
    public event CancelEventHandlerAsync ChildModuleLaunching;

    public async Task Launch()
    {
         var cancelEventArgs = new CancelEventArgsAsync();
         this.ChildModuleLaunching(this, cancelEventArgs);
         cancelEventArgs.WaitForDefferalsAsync();
         if (cancelEventArgs.Cancel) 
         {
             return;
         }

         Console.WriteLine("Child module 1 launched."); // This should not be executed.
     }
}

然后订阅子模块事件的父类:

public class Parent
{
    private ChildModule1 child1 = new ChildModule1();

    public Parent()
    {
        this.child1.ChildModuleLaunching += this.OnChildModule1Launching;
    }

    public async Task Process()
    {
        await this.child1.Launch();
    }

    private async void OnChildModule1Launching(object sender, CancelEventArgsAsync e)
    {
        var deferral = e.GetDeferral();

        await Task.Delay(2500); // Simulate processing of an awaitable task.
        e.Cancel = true;

        deferral.Dispose();
    }
}

最后,控制台应用入口点:

static void Main(string[] args)
{
    var parent = new Parent();

    parent.Process().Wait();

    Console.ReadKey();
}

1 个答案:

答案 0 :(得分:2)

您需要await WaitForDefferalsAsync来电:

await cancelEventArgs.WaitForDefferalsAsync();