yudjin
|
|
« : 04-03-2011 08:13 » |
|
Добрый день. Что выведется на консоль после первого эникея? А после второго?? Почему так? Я знаю, что ГК работают "случайно" и не гарантируют вызов деструктора, как-только количество ссылок на объект будет равно 0, но все же... Как сделать, чтоб выводило то, что хочет программист? class Task { public event EventHandler Completed; public void OnCompleted() { if (Completed != null) Completed(this, EventArgs.Empty); } }
class Sheduller { public Sheduller(Task task ) { Console.WriteLine("Create"); task.Completed += delegate { Console.WriteLine("Completed"); }; }
~Sheduller() { Console.WriteLine("Destroy"); } }
class Program { static void Main(string[] args) { Sheduller sheduller; { Task task = new Task(); sheduller= new Sheduller(task); sheduller= new Sheduller(task); //Ссылка на первый экземпляр sheduller потеряна sheduller= new Sheduller(task); //Ссылка на второй экземпляр sheduller потеряна task .OnCompleted(); Console.ReadKey(); } Console.ReadKey(); } }
Что хочет программист: Необходимо, чтобы после трех Create выводился ОДИН Completed, т.к. по его скромному мнению сейчас живет один экземпляр класса Sheduller
|
|
« Последнее редактирование: 04-03-2011 08:29 от yudjin »
|
Записан
|
|
|
|
Dale
|
|
« Ответ #1 : 04-03-2011 09:00 » |
|
Что хочет программист: Необходимо, чтобы после трех Create выводился ОДИН Completed, т.к. по его скромному мнению сейчас живет один экземпляр класса Sheduller И как он себе это мыслит, если на обработчик события Completed подписалось целых три анонимных делегата?
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
yudjin
|
|
« Ответ #2 : 04-03-2011 09:09 » |
|
Мыслю так. Делегат указывает на функцию, принадлежащую объекту sheduller. Ссылки на первые два объекта класса Sheduller обнулились, когда создали третий объект. Значит, Console.WriteLine("Completed"); должно вызваться только для третьего объекта.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #3 : 04-03-2011 09:14 » |
|
Наверное всё-таки имеется ввиду scheduler. В тему. Нууу можно, например, заменить программиста. Если это сделать невозможно, по той или иной причине, то попробуй сам решить проблему. Подсказка Nr.1. Начни с алгоритма. Опиши словами, что у тебя происходит, как изменяется объект task. И всё сразу станет ясно. Если не станет, то см. Подсказку Nr.2
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Dale
|
|
« Ответ #4 : 04-03-2011 09:29 » |
|
Мыслю так. Делегат указывает на функцию, принадлежащую объекту sheduller. На какую именно?
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
yudjin
|
|
« Ответ #5 : 04-03-2011 09:34 » |
|
Начни с алгоритма. Опиши словами, что у тебя происходит, как изменяется объект task.
вот из-за этой ссылки task.Completed += delegate { Console.WriteLine("Completed"); }; объект класса Sheduller висит в памяти, ГК его не трогает? dale на анонимную. Сделал ее очевидной. Тогда перед созданием нового экземпляра нужно у старого удалять делегат. Плохой план...
|
|
« Последнее редактирование: 04-03-2011 09:37 от yudjin »
|
Записан
|
|
|
|
baldr
|
|
« Ответ #6 : 04-03-2011 09:38 » |
|
yudjin, а почему не использовать статическую переменную и Interlocked.Increment()/Interlocked.Decrement() ?
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #7 : 04-03-2011 10:18 » |
|
baldr, а ещё лучше использовать слабые ссылки - класс WeakReference.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Dale
|
|
« Ответ #8 : 04-03-2011 10:32 » |
|
dale на анонимную. А каким образом эта анонимная функция принадлежит объекту? И почему она обязана автоматически исчезать из multicast-делегата при удалении экземпляра?
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
yudjin
|
|
« Ответ #9 : 04-03-2011 10:44 » |
|
То, что анонимный метод принадлежит объекту - я не сомневаюсь. А вот почему она не удаляется из multicast-делегата при удалении экземпляра ... Наверное, сам экземпляр не удаляется из памяти, т.к. этот самый делегат ссылается на анонимный метод объекта и держит его в памяти. В общем, все ясно - у меня изначально неверный подход.
|
|
« Последнее редактирование: 04-03-2011 12:33 от yudjin »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #10 : 04-03-2011 13:20 » |
|
yudjin, убедительная просьба: задавай осмысленное название темы.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|