AsyncEx DeferralManager для ожидания обработчиков событий

1

У меня есть аналогичная проблема, изложенная в этой теме, и, по словам Стивена Клири, решение WinRT - использовать отсрочки. Решение, указанное в потоке, также работает для меня, но я хотел попробовать использовать отсрочки, так как это может быть или стать стандартным способом обработки такой ситуации.

Поэтому я прочитал его блог об этом и попытался применить его к моему коду, но я не могу заставить его работать. Что происходит, так это то, что подписка на события все еще не ожидается. Я также не смог найти полную пробную программу, которую я могу запустить и проанализировать. Поэтому я попытался создать примерную консольную программу, чтобы продемонстрировать проблему, которую я видел.

Сначала у меня есть определения делегата и аргументы аргументов обработчика события:

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();
}
Теги:
async-await

1 ответ

2
Лучший ответ

Вам нужно await вызова WaitForDefferalsAsync:

await cancelEventArgs.WaitForDefferalsAsync();
  • 0
    Круто, от самого Стивена Клири. Интересно. Это сработало, спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню