Обновление : я написал программу , чтобы проверить значение памяти для каждого из методов, которые я упоминаю ниже.Не слишком удивительно, я обнаружил, что, конечно же, традиционный подход с использованием событий .NET создает гораздо больше мусора, чем другие подходы (то есть фактически он создает мусор, в отличие от двух других стратегий).что, похоже, не создает никакого мусора вообще).
Действительно, я должен был все время подчеркивать, что меня больше интересует память накладные расходы TEventArgs
аргументов в событиях .NETчем стоимость с точки зрения скорость .В конечном счете, я должен признать, что для всех практических целей - с точки зрения скорости памяти и - затраты незначительны.Тем не менее, я подумал, что было бы интересно увидеть, что повышение многих событий «обычным» способом стоит стоит что-то - и что в крайних случаях это может даже привести к поколению 1сборки мусора, которые могут иметь или не иметь значения в зависимости от ситуации (по моему опыту, чем больше должна быть система в реальном времени, тем важнее помнить, где создается мусор и как его минимизировать)при необходимости).
Это может показаться глупым вопросом.Я понимаю, что Windows Forms, например, можно легко считать «высокопроизводительным» сценарием, когда сотни или даже тысячи событий возникают очень быстро (например, событие Control.MouseMove
) постоянно.Но все же я задаюсь вопросом, действительно ли разумно проектировать класс с событиями .NET, когда ожидается, что этот класс будет использоваться в высокопроизводительном, критичном ко времени коде.
Основная проблема, которую я имею, связана ссоглашение, что каждый использует что-то вроде EventHandler<TEventArgs>
для всех событий, где TEventArgs
происходит от EventArgs
и, по всей вероятности, является классом, который должен создаваться каждый раз, когда событие вызывается / обрабатывается.(Если это просто EventsArgs
, очевидно, это не тот случай, когда можно использовать EventArgs.Empty
; но при условии, что любая значимая и непостоянная информация содержится в типе TEventArgs
, создание экземпляра будетвероятно, понадобится.) Кажется, что это приводит к большему давлению ГХ, чем я ожидал бы для создания высокопроизводительной библиотеки.
Тем не менее, единственные альтернативы, о которых я могу подумать:
- Использование нетрадиционных типов делегатов (т. Е. Не
EventHandler<TEventArgs>
) для событий, получение только параметров, которые не требуют создания экземпляров объекта, таких как int
, double
и т. Д. (Даже string
, и передача ссылокк существующим строковым объектам). - Пропуск событий вообще и использование виртуальных методов, заставляя клиентский код переопределять их по желанию.Похоже, что это в основном тот же эффект, что и в предыдущей идее, но несколько более контролируемым образом.
Являются ли мои опасения по поводу давления GC событий .NET необоснованными с самого начала?Если так, что я там пропускаю?Или есть какая-то третья альтернатива, которая лучше, чем две, которые я только что перечислил?