У меня есть аналогичная проблема, изложенная в этой теме, и, по словам Стивена Клири, решение 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();
}
Вам нужно await
вызова WaitForDefferalsAsync
:
await cancelEventArgs.WaitForDefferalsAsync();