Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.03.2016, 11:38   #1
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
Лампочка WeakEventManager. Как эта штука работает???

Что-то события мне тяжко даются. Кто-нибудь может объяснить как работает данный класс. Точнее сказать унаследованный от него класс?
По словам автора книги, он поможет освобождать память, если вдруг прослушиватель исчезнет раньше, чем издатель. Т.е. как я понял, если у нас прослушиватель напрямую подключен к издателю, и экземпляр прослушивателя выходит за рамки видимости кода или мы его пытаемся удалить, то он не удалится, поскольку ссылка на него сохранена в издателе. Правильно я понял? Соответственно у нас неиспользуемый экземпляр класса будет занимать место в памяти, что ни есть хорошо. А вот этот шаблон поможет нам освобождать это место. Но я не могу понять каким образом. Вроде теже самые действия, но только через свои методы.
Вот пример кода класса производного от шаблона из книги:
Код:
public class WeakCarInfoEventManager: WeakEventManager
{
	public static void AddListener(object source, IWeakEventListener listener)
	{
		CurrentManager.ProtectedAddListener(source, listener);
		Console.WriteLine("{0} have a new listener", source.dealer);
	}
	public static void RemoveListener(object source, IWeakEventListener listener)
	{
		CurrentManager.ProtectedRemoveListener(source, listener);
		Console.WriteLine("{0} lost a listener", source.dealer);
	}
	public static WeakCarInfoEventManager CurrentManager
	{
		get
		{
			var manager=GetCurrentManager(typeof(WeakCarInfoEventManager)) as WeakCarInfoEventManager;
			if (manager==null)
			{
				manager=new WeakCarInfoEventManager();
				SetCurrentManager(typeof(WeakCarInfoEventManager), manager);
			}
			return manager;
		}
	}
	protected override void StartListening(object source)
	{
		(source as CarDealer).NewCarInfo+=CarDealer_NewCarInfo;
	}
	void CarDealer_NewCarInfo(object sender, CarInfoEventArgs e)
	{
		DeliverEvent(sender,e);
	}
	protected override void StopListening(object source)
	{
		(source as CarDealer).NewCarInfo=CarDealer_NewCarInfo;
	}
}
Может кто растолковать как это работает? Просто не очень хочется принимать это, как аксиому. Сознание требует доказательств.
И да. Есть еще одна проблема. Когда я использую этот класс и подключаю пространство имен System.Windows компилятор отказывается видеть базовый класс WeakEventManager. И выдает следующее:
Код:
prog.cs(64,23): error CS0246: The type or namespace name `IWeakEventListener' could not be found. Are you missing an assembly reference?
prog.cs(84,39): error CS0246: The type or namespace name `WeakEventManager' could not be found. Are you missing an assembly reference?
Кстати, забыл сказать, когда в 2008 студии пишу "using System.Windows", то после точки он мне не предлагает выбора Windows. Это вполне объясняет, почему компилятор не видит WeakEventManager. Правда версия C# 3.5. При этом на msdn`е указывается, что доступно с версии 3.0.
С чем это может быть связано?

Последний раз редактировалось max_prorok; 17.03.2016 в 13:22.
max_prorok вне форума Ответить с цитированием
Старый 17.03.2016, 16:17   #2
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Итак, у меня появились некоторые домыслы по поводу работы этого шаблона.
Хочу поделиться ими с вами, и хочу услышать ваше мнение, прав я или нет.

Есть у меня догадки, что внутри этого класса есть групповой делегат или еще какая-то переменная, которая держит в себе методы RecieveWeakEvent из интерфейса IWeakEventListener, от которого должны наследоваться классы-прослушиватели. При этом, метод RecieveWeakEvent держит в себе обработчик. Назовем ее ListenerList. Изначально, эта переменная пуста.
Когда мы вызываем метод AddListener, мы обращаемся к базовому методу ProtectedAddListener, который добавляет наш обработчик в переменную ListenerList, а за одно и проверяет, была ли наша переменная ListenerList пустая. И если ListenerList была пуста, то запускает метод StartListening, который всего лишь подписывает на событие издателя метод CarDealer_NewCarInfo, в котором идет вызов метода DeliverEvent базового класса. А DeliverEvent непосредственно пробегает по всей ListenerList и вызывает методы, которые в нее записаны.
В случае, если мы с помощью метода RemoveListener удалим все обработчики из переменной ListenerList, то вызовется метод StopListening, который в свою очередь в подписках оставляет только метод CarDealer_NewCarInfo, который вызывает метод базового класса DeliverEvent. Но поскольку, внутри ListenerList пусто, то он соответственно не вызывает никаких обработчиков.

Теория моя хороша, но есть в ней один тонкий момент, который для меня остался загадкой. А именно: если все так и есть как я описал, то зачем в методе StartListening использовать именно такую строку:
Код:
(source as CarDealer).NewCarInfo+=CarDealer_NewCarInfo;
а не просто:
Код:
(source as CarDealer).NewCarInfo=CarDealer_NewCarInfo;
И не ясно зачем тогда нужен метод StopListening.

Последний раз редактировалось max_prorok; 17.03.2016 в 16:43.
max_prorok вне форума Ответить с цитированием
Старый 17.03.2016, 16:24   #3
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Цитата:
Сообщение от max_prorok Посмотреть сообщение
А именно: если все так и есть как я описал, то зачем в методе StartListening использовать именно такую строку:
Код:
(source as CarDealer).NewCarInfo+=CarDealer_NewCarInfo;
а не просто:
Код:
(source as CarDealer).NewCarInfo=CarDealer_NewCarInfo;
На счет этого есть предположение, чтобы сработал add внутри определения события.
И остается вопрос тогда касаемо StopListening. И собственно вопрос касаемо освобождения памяти. Если код вышел за пределы видимости экземпляра класса-прослушивателя, но при этом ссылка на его метод осталась внутри ListeningList, то каким образом тогда сборщик мусора удалит его?

P.S. Ну и вопрос не виденья System.Windows так же остается открытым.

Последний раз редактировалось max_prorok; 17.03.2016 в 16:27.
max_prorok вне форума Ответить с цитированием
Старый 17.03.2016, 16:51   #4
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Кажется решил вопрос с невиденьем System.Windows. Дело в том, что это пространство имен находится в сборке WindowsBase, соответственно, в библиотеке WindowsBase.dll. А я ее не подключал, поэтому и не видит.
max_prorok вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Объясните как эта прога работает. МаксDragon Паскаль, Turbo Pascal, PascalABC.NET 2 13.12.2014 00:00
как работает эта программа? C++ степень severest Помощь студентам 7 03.07.2012 21:48
Объясните как работает эта функция перевода из десятичной в восмеричную систему? severest Помощь студентам 1 02.07.2012 05:57
как работает эта программа(Алгоритм Рабина-Карпа с++)??? Lodas Общие вопросы C/C++ 1 18.12.2011 11:58
На чём зделана эта штука HellMercenariess PHP 3 04.08.2009 13:01