Подтвердить что ты не робот

Почему реализация событий на С# не используется по умолчанию для шаблона слабых событий?

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

Шаблон события в поддерживает оживление подписчика пока издатель события жив. Таким образом, если вы не откажетесь от подписки, вы пропустите память (ну, на самом деле, не утечка), но память остается занятой без необходимости).

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

С шаблоном события, вызывающим так много проблем (для новичков?), возникает вопрос: почему было принято решение, что издатель сохраняет сильную ссылку на подписчика, вместо того, чтобы сделать их независимыми или позволить разработчикам явно иметь strong или weak?

Здесь уже есть пара questions, и ответы звучат разумно, но никто не отвечает, почему это так.

4b9b3361

Ответ 1

Одна из причин - это производительность. Ручки GC (которые задействуют все "экзотические" ссылки, такие как WeakReference), имеют стоимость исполнения. Слабые события медленнее, чем "сильные" события, поскольку для них требуется ручка GC. Сильное событие реализуется (по умолчанию) полем экземпляра, хранящим делегат. Это просто обычная управляемая ссылка как дешевая, как любая другая ссылка.

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

Также существует семантическая разница и недетерминированность, которая будет вызвана слабыми ссылками. Если вы подключите () => LaunchMissiles() к некоторому событию, вы можете обнаружить, что ракеты запускаются только иногда. В других случаях GC уже убрал обработчик. Это можно решить с помощью зависимых ручек, которые вносят еще один уровень сложности.

Обратите внимание, что вы можете реализовать слабые события самостоятельно прозрачно для подписчика. События подобны свойствам в том смысле, что они являются просто метаданными и соглашениями, основанными на методах доступа add и remove. Итак, это (просто) вопрос о значениях по умолчанию, которые выбрали языки .NET. Это не вопрос дизайна CLR.

Я лично считаю редким, что серьезный реферирующий характер событий является проблемой. Часто события подключаются между объектами, которые имеют одинаковое или очень сходное время жизни. Например, вы можете подключать все события, которые вы хотите, в контексте HTTP-запроса в ASP.NET, потому что все будет иметь право на сбор при завершении запроса. Любые утечки ограничены по размеру и недолговечны.