Что произойдет, если обработчик событий C# утилизируется и я вызову его?

Этот вопрос является продолжением вопроса C# Events and Thread Safety (я не являюсь автором этого вопроса) и соответствующей записи в блоге Эрика Липперта Events and Races. Есть и другие подобные вопросы на SO, но ни один из них не рассматривает этот случай, общее мнение таково, что пока вы отписываетесь, вы в безопасности, но я не верю, что это так всегда.

Согласно обсуждению в вопросе на SO и в блоге, шаблон, который следует использовать, выглядит примерно так:

var ev = NotifyPropertyChanged;
if (ev != null)
    ev(this, new PropertyChangedEventArgs("Foo"));

Но что если произойдет следующая ситуация:
1) Я подписываюсь на слушателя:

mytype.NotifyPropertyChanged += Handler; // Handler is instance method in SomeObject class

2) Я (или время выполнения, из-за масштабирования) избавляюсь от SomeObject, который содержит слушателя, и отписываюсь от слушателя, примерно в то же время, когда происходит уведомление о свойстве.

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

Согласно Eric Lippert, "обработчики событий обязаны быть устойчивыми к вызову даже после того, как событие было отписано". Но если обработчик отписан и утилизирован , он больше не может обслуживать вызов. Как правильно поступить в данной ситуации?

Завернуть код из (1) в try-catch? Какое исключение должно быть поймано? ObjectDisposedException кажется вероятным, но не единственным, которое может произойти, я думаю.

7
задан Community 23 May 2017 в 12:25
поделиться