Генерирование событий в C#, которые игнорируют исключения, повышенные обработчиками

Один из моих главных объектов неприязни с генерированием событий в C# является тем, что исключение в обработчике событий будет взламывать мой код и возможно препятствовать тому, чтобы другие обработчики были названы, если поврежденный, оказалось, назвали первым; В большинстве случаев мой код не мог заботиться меньше, если чей-либо код, это слушает его события, взломан.

Я создал дополнительный метод, который ловит исключения:

public static void Raise(this EventHandler eh, object sender, EventArgs e)
{
  if (eh == null)
    return;
  try
  {
    eh(sender, e);
  }
  catch { }
}

Хотя это действительно означает, что мой код продолжается независимо, этот метод не останавливает первый обработчик событий, выдающий исключение и предотвращающий вторые и последующие обработчики, уведомляемые относительно события. Я изучаю способ выполнить итерации через GetInvocationList для обертывания каждого обработчика одиночных соревнований в свою собственную попытку/выгоду, но это кажется неэффективным, и я не уверен в лучшем способе сделать это, или даже если я должен быть.

Кроме того, я действительно не удобен просто игнорирование исключения здесь (и ни один не FxCop/Resharper в этом отношении); реалистично, что должно произойти с исключением в этом случае?

9
задан Flynn1179 24 June 2010 в 09:59
поделиться

4 ответа

Что, если бы вы сделали что-то подобное?

public static void Raise(this EventHandler eh, object sender, EventArgs e)
{
    if (eh == null)
        return;

    foreach(var handler in eh.GetInvocationList().Cast<EventHandler>())
    {
        try
        {
            handler(sender, e);
        }
        catch { }
    }
}
3
ответ дан 3 November 2019 в 00:58
поделиться

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

Если ваш код не может обработать исключение, не отлавливайте его.

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

3
ответ дан 3 November 2019 в 00:58
поделиться

Если обработчик события не перехватил исключение, я не вижу хорошего способа обработать исключение в классе, генерирующем событие. У вас нет контекста, чтобы знать, что делает обработчик. В этом случае безопаснее всего позволить приложению сильно упасть, поскольку вы не знаете, какие побочные эффекты мог вызвать другой обработчик событий, которые могут дестабилизировать ваше приложение. Урок здесь в том, что обработчики событий должны быть устойчивыми (обрабатывать собственные исключения), поскольку классы, запускающие события, никогда не должны перехватывать исключения, создаваемые обработчиками.

3
ответ дан 3 November 2019 в 00:58
поделиться

Простое, но важное правило:

Каждый дефект в коде должен быть таким, как смертельный как можно раньше возможный.

Таким образом, ошибки обнаруживаются и исправляются, а программное обеспечение становится все сильнее. То, что говорят другие, правильно; никогда не ловите исключение, которого вы не ожидаете и знаете, как с ним справиться.

2
ответ дан 3 November 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: