В System.ComponentModel есть класс CancelEventArgs, который содержит член Cancel, который может быть установлен в слушателях событий. В документации на MSDN объясняется, как использовать это для отмены событий из слушателя, но как использовать его для реализации моих собственных отменяемых событий? Есть ли способ проверить член Cancel после срабатывания каждого слушателя, или мне нужно подождать, пока событие не запустит все его слушатели?





Чтобы проверить каждого слушателя по очереди, вам нужно вручную получить обработчики через GetInvocationList:
class Foo
{
public event CancelEventHandler Bar;
protected void OnBar()
{
bool cancel = false;
CancelEventHandler handler = Bar;
if (handler != null)
{
CancelEventArgs args = new CancelEventArgs(cancel);
foreach (CancelEventHandler tmp in handler.GetInvocationList())
{
tmp(this, args);
if (args.Cancel)
{
cancel = true;
break;
}
}
}
if (!cancel) { /* ... */ }
}
}
Я также хотел бы узнать ответ на вышеприведенный комментарий о том, почему важно, чтобы другие слушатели не получали событие Before.
Представьте себе двух подписчиков на одно и то же событие (в одном объекте). Один устанавливает cancel = true, а второй - «cancel = false». Как вы думаете, что это произойдет? Ответ показывает, как избежать такой ситуации. Если хотя бы один подписчик отменяет мероприятие, оно отменяется. Период.
Пока этот код будет работать, это нормальная работа CancelEventHandler? Разве они обычно не используются в паттернах BeforeX, AfterX, где если что-то в Before устанавливает Canel, то X не происходит, поэтому AfterX не вызывается. Почему важно, чтобы другие слушатели не получали событие «До»?