Должны ли аргументы отменяемого события передаваться всем обработчикам, если первый обработчик отменяет их? - PullRequest
1 голос
/ 07 апреля 2011

У меня есть метод расширения, который вызывает отменяемые события, возвращая bool, если они отменены:

public static bool RaiseCancel<T>(this EventHandler<T> ev, object sender, T e) where T : CancelEventArgs
{
    if (ev == null)
    {
        return false;
    }

    foreach (Delegate del in ev.GetInvocationList())
    {
        try
        {
            ISynchronizeInvoke invoke = del.Target as ISynchronizeInvoke;
            if (invoke != null && invoke.InvokeRequired)
            {
                invoke.Invoke(del, new[] { sender, e });
            }
            else
            {
                del.DynamicInvoke(sender, e);
            }
        }
        catch (TargetInvocationException ex)
        {
            throw ex.InnerException;
        }

        // if (e.Cancel) return true;
    }

    return e.Cancel;
}

Однако, я не могу не думать, что он должен немедленно вернуться, когда обработчик отменяет его ради эффективности, а не продолжать вызывать оставшиеся обработчики. Насколько мне известно, ни один обработчик отменяемого события НИКОГДА не должен предпринимать никаких действий, кроме как установить для свойства Cancel значение true. В таком случае, какой смысл просить больше обработчиков принять решение, которое уже принято? С другой стороны, кажется неправильным НЕ вызывать обработчик события, когда это происходит, если объект прослушивает событие.

Должен ли я раскомментировать оператор if (и заменить возвращаемое значение в конце метода на return false;) или нет?

РЕДАКТИРОВАТЬ: Я полагаю, если вы собираетесь продолжать вызывать обработчики, должен ли я позволять самим обработчикам принимать решение (то есть, они могут иметь if (e.Cancel) return; в начале обработчика), если они хотят?

1 Ответ

3 голосов
/ 07 апреля 2011

ПРИМЕЧАНИЕ: здесь я описываю только то, что, на мой взгляд, имеет смысл. Это может быть реализовано не так в .NET Framework (см. Комментарий Жоао Анджело ниже)

Взять пример: событие FormClosing. Если обработчик отменяет это событие, форма не будет закрыта, поэтому нет смысла уведомлять другие обработчики о том, что форма закрывается.

В более общем случае, если вы вызываете другие обработчики после того, как e.Cancel имеет значение true, вы уведомляете их о том, что больше не происходит ...

Так что, по моему мнению, вам следует прекратить вызывать обработчики, как только для e.Cancel будет установлено значение true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...