Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Конструирование типа с множеством событий




В предыдущем разделе я описал ситуацию, в которой могут понадобиться явные методы-аксессоры add и remove события. Когда вы создаете явную реализацию аксессоров сами, у вас немного больше свободы творчества. Рассмотрим, как при помощи явной реализации этих методов можно уменьшить использование памяти приложением.

Тип SystemWindowsForms.Control определяет около 70 событий. Если бы тип Control реализовал эти события, позволяя компилятору неявно генерировать аксессоры add и remove и поля делегатов, то у каждого объекта типа Control пришлось бы создавать 70 полей делегатов лишь для одних событий! Поскольку объекты никогда не регистрируются для уведомления о большинстве из этих событий, то при создании каждого объекта типа, производного от Control, огромное количество памяти просто пропадало бы зря. Кстати, тип System.Web.UI.Control также использует технологию, о которой пойдет речь ниже, чтобы сэкономить память, которая в противном случае напрасно тратится на обслуживание неиспользуемых событий.

Если подойти к явной реализации методов add и remove творчески, можно значительно уменьшить объем памяти, бесполезно затраченной каждым объектом. В этом разделе я покажу, как определить тип, способный эффективно поддерживать множество событий.

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

Когда объект должен инициировать событие, происходит его поиск в наборе. Если там нет элемента для этого идентификатора события, следовательно, ни один объект не требует уведомления о нем, и никакого обратного вызова какого-либо делегата не требуется. Если событие в наборе есть, вызывается список делегатов, ассоциированный с событием. Реализация этой архитектуры остается на совести программиста, разрабатывающего тип, в котором определены соответствующие события; разработчик, использующий тип, ничего не знает о внутренней реализации событий.

Как реализовать все описанное выше, демонстрирует приложение-пример TypeWithLotsOfEvents, которое можно скачать с сайта http://wintellect.com. Код оснащен подробными комментариями, и, если вы поняли все сказанное ранее в этой главе, у вас не будет проблем с его пониманием и адаптацией для решения собственных задач.

Примечание: в моем коде используется вспомогательный класс EventSet, который поддерживает словарь идентификаторов-ключей событий и значений делегатов. В FCL определен тип System.ComponentModel.EventHandlerList, который делает в сущности то же, что и мой тип EventSet. Типы System.WindowsForms.Control и SystemWeb.UI.Control внутренне используют тип EventHandlerList для обслуживания своих разреженных наборов событий. Вы, несомненно, можете использовать определенный в FCL тип EventHandlerList. Разница между EventHandlerList и моим типом EventSet в том, что EventHandlerList использует связный список вместо хеш-таблицы. Это означает, что тип EventHandlerList не поддерживает доступ к набору, обеспечивающий безопасность потоков. Если требуется безопасность потоков, вам придется самим создавать оболочку для набора EventHandlerList. Мой класс EventSet обеспечивает полную безопасность потоков.



Поделиться:

Дата добавления: 2015-04-21; просмотров: 67; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.006 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты