Обработчики событий, не ориентированные на многопотоковое исполнение? [дубликат]

29
задан abatishchev 28 February 2013 в 01:07
поделиться

4 ответа

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

Проблема с потоками заключается в том, что они могут добавлять или удалять элементы из этой коллекции путем подписки / отказа от подписки. Если они сделают это во время итерации коллекции, это вызовет проблемы (я думаю, что возникает исключение)

Цель состоит в том, чтобы скопировать список перед его повторением, чтобы вы были защищены от изменений в списке.

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

14
ответ дан 28 November 2019 в 01:32
поделиться

Лучшая практика - вторая форма. Причина в том, что другой поток может обнулить или изменить SomeEvent между тестом « if » и вызовом.

5
ответ дан 28 November 2019 в 01:32
поделиться

Здесь хорошая статья о событиях .NET и условиях гонки с потоками. Он охватывает некоторые распространенные сценарии и содержит несколько полезных ссылок.

Надеюсь, это поможет.

2
ответ дан 28 November 2019 в 01:32
поделиться

ИМО, другие ответы упускают одну ключевую деталь - делегаты (и, следовательно, события) неизменяемы . Смысл этого в том, что подписка или отмена подписки на обработчик событий не просто добавляет / удаляет список - скорее, он заменяет список новым с дополнительным (или одним предметом меньше) на нем.

Поскольку ссылки являются атомарными, это означает, что в момент, когда вы делаете:

var handler = SomeEvent;

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

Итак, вы проверяете значение null и вызываете его, и все в порядке. Обратите внимание, конечно, что существует все еще запутанный сценарий события, вызванного на объекте, который думает, что он отписался от подписки пикосекунду назад!

32
ответ дан 28 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

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