Этот вопрос является продолжением вопроса C # и безопасности потока (я не являюсь его автором) и соответствующего сообщения в блоге Эрика Липперта События и гонки, Есть и другие подобные вопросы по 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 сохраняет старого абонента, который больше не существует, он вызовет функцию в объекте которые больше не существуют.
По словам Эрика Липперта, «обработчики событий должны быть устойчивыми перед вызовом даже после того, как событие было отписано ». Но если обработчик отписался и утилизировал , он больше не может заботиться о вызове. Как правильно справиться с этой ситуацией?
Свернуть код из (1) в try-catch? Какое исключение следует поймать? Кажется вероятным, что ObjectDisposedException, но не единственный, который может произойти.