Существует следующий шаблон, который используется, чтобы избежать состояния гонки при возникновении событий в случае, если другой поток отменит подписку на MyEvent, сделав его нулевым.
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
EventHandler handler = MyEvent;
if(handler != null)
handler(this, EventArgs.Empty);
}
}
в отличие от неправильного способа сделать это. склонны к этому состоянию гонки:
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
if(MyEvent != null)
MyEvent(this, EventArgs.Empty);
}
}
У меня вопрос, учитывая, что System.Delegate
является ссылочным типом: в случае, если MyEvent не равно null, почему
EventHandler handler = MyEvent;
кажется копией его список вызовов вместо получения ссылки.
Я ожидал бы, что если делегат MyEvent назначен переменной 'handler', то, как только кто-то изменит MyEvent, объект, который ' ссылки обработчика также будут изменены.
Очевидно, что это не так, иначе этот изящный маленький шаблон не работал бы.
I 'Я заглянул в исходный код .NET и все еще не нашел там своего ответа (он, вероятно, есть, но я искал его около часа и не нашел, так что вот я). Я также читал, что Спецификация языка C # говорит о событиях и делегатах, но это не касается этого вопроса.
Спасибо за ваше время.