1 2 3 4
А нормально ли отписываться от событий в Dispose в избранное  новое горячее всё    подписка   модер. 
От: Sshurhttp://shurygin-sergey.livejournal.com
Дата: 08.02.10 10:35
Привет, All!


Пришлось тут ковыряться с мемори ликами, основной причиной которых были неотписанные обработчики событий.. Причем такая весьма хитрая зависимость получилась, готовые компоненты одной известной фирмы подписывались на события некоторого глобального объекта в конструкторе, а отписывались в Dispose, а Dispose-то я не вызывал

С Dispose я конечно сам виноват, но все-таки хотелось бы разобраться, это нормальная практика или нет? В MSDN написано, что Dispose служит для освобождения неуправляемых ресурсов, а никак не для отписывания от событий. И если забыть позвать Dispose, то вместо ожидаемых каких-то неосвобожденных ресурсов получаем неограниченно висящий в памяти объект, который возможно держит кучу других. Это уже как-то совсем неправильно получается..
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 08.02.10 10:51
Здравствуйте, Sshur, Вы писали:

S>С Dispose я конечно сам виноват, но все-таки хотелось бы разобраться, это нормальная практика или нет?


Нормальная.

S>В MSDN написано, что Dispose служит для освобождения неуправляемых ресурсов, а никак не для отписывания от событий.


Не помню, что бы где-то говорилось именно про неуправляемые и не говорилось бо управляемых. Со времени выхода второго фреймворка использовать Dispose для освобождения неуправляемых ресурсов как раз не обязательно (такие, неуправляемые, ресурсы принято оборачивать в [одного из наследников] CriticalFinalizerObjectздесь подробнее). Для Dispose остаётся только задача освобождения управляемых ресурсов — вызов Dispose внутренних объектов и отписка от событий внешних объектов в том числе.

S>И если забыть позвать Dispose, то вместо ожидаемых каких-то неосвобожденных ресурсов получаем неограниченно висящий в памяти объект, который возможно держит кучу других. Это уже как-то совсем неправильно получается..


Общее правило таково — если создали Disposabe-объект, то обязательно освободите его. Если получили объект извне (тут уже речь о любом объекте, не обязательно disposable) — или примите владение объектом на себя (пока жив ваш объект, должен жить и "пришедший" внешний и наоборот) или обеспечьте, что бы жизненный цикл внешнего объекта не зависел от жизненного цикла вашего объекта.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Lloyd 
Дата: 08.02.10 10:53
Здравствуйте, Sshur, Вы писали:

S>С Dispose я конечно сам виноват, но все-таки хотелось бы разобраться, это нормальная практика или нет? В MSDN написано, что Dispose служит для освобождения неуправляемых ресурсов, а никак не для отписывания от событий.


Там такого не написано. Вот цитата:

The primary use of this interface is to release unmanaged resources.

Тот факт, что освобождение ресурсов — primary use, не отменяет возможность существовани secondary use.

Но лично я не стал бы помещать отписку от событий в Dispose, т.к. тогда в сам класс придется тащить ссылку на объект-источник события, что не очень хорошо, т.к. ведет к болшей связности. Тот, кто подписывал, тот и должен отписывать объект от событий.
Re[2]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Sshurhttp://shurygin-sergey.livejournal.com
Дата: 08.02.10 10:59
Здравствуйте, _FRED_, Вы писали:



S>>И если забыть позвать Dispose, то вместо ожидаемых каких-то неосвобожденных ресурсов получаем неограниченно висящий в памяти объект, который возможно держит кучу других. Это уже как-то совсем неправильно получается..


_FR>Общее правило таково — если создали Disposabe-объект, то обязательно освободите его. Если получили объект извне (тут уже речь о любом объекте, не обязательно disposable) — или примите владение объектом на себя (пока жив ваш объект, должен жить и "пришедший" внешний и наоборот) или обеспечьте, что бы жизненный цикл внешнего объекта не зависел от жизненного цикла вашего объекта.


Насчет сам создал — сам уничтожь согласен. Но вот отписка от событий в Dispose чем-то смущает...
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[2]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: MozgChttp://nightcoder.livejournal.com
Дата: 08.02.10 11:03
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>Но лично я не стал бы помещать отписку от событий в Dispose, т.к. тогда в сам класс придется тащить ссылку на объект-источник события, что не очень хорошо, т.к. ведет к болшей связности. Тот, кто подписывал, тот и должен отписывать объект от событий.


Так этот же объект и подписывался в конструкторе.
Re[2]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Sshurhttp://shurygin-sergey.livejournal.com
Дата: 08.02.10 11:04
Здравствуйте, Lloyd, Вы писали:


L>Там такого не написано. Вот цитата:

L>

L>The primary use of this interface is to release unmanaged resources.

L>Тот факт, что освобождение ресурсов — primary use, не отменяет возможность существовани secondary use.

Ну да.

L>Но лично я не стал бы помещать отписку от событий в Dispose, т.к. тогда в сам класс придется тащить ссылку на объект-источник события, что не очень хорошо, т.к. ведет к болшей связности. Тот, кто подписывал, тот и должен отписывать объект от событий.


Если класс сам подписался на событие какого-то внешнего объекта, то ссылка на него уже есть.. А в моем случае тот внешний объект вообще глобальный синглтон
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[3]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Lloyd 
Дата: 08.02.10 11:06
Здравствуйте, MozgC, Вы писали:

MC>Так этот же объект и подписывался в конструкторе.


Да, проглядел. +1.
Re[3]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Lloyd 
Дата: 08.02.10 11:07
Здравствуйте, Sshur, Вы писали:

L>>Но лично я не стал бы помещать отписку от событий в Dispose, т.к. тогда в сам класс придется тащить ссылку на объект-источник события, что не очень хорошо, т.к. ведет к болшей связности. Тот, кто подписывал, тот и должен отписывать объект от событий.


S>Если класс сам подписался на событие какого-то внешнего объекта, то ссылка на него уже есть.. А в моем случае тот внешний объект вообще глобальный синглтон


Тогда все нормально. Никаких противопоказаний в этом случае я не вижу.
Re[3]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 08.02.10 11:48
Оценка: +1
Здравствуйте, Sshur, Вы писали:

S>Насчет сам создал — сам уничтожь согласен. Но вот отписка от событий в Dispose чем-то смущает...


А где ещё её делать, если подписываешься в конструкторе? Именно Dispose иесть самое подходящее место, как антипод конструктора. Вот если подписываешься в сеттере какого-либо свойства:
class X
{
  private SomeResource parent;

  public SomeResource Parent {
    get { return parent; }

    set {
      UnwireParent(); Отписываемся там же…
      parent = value;
      WireParent(); // …где и подписываемся
    }
  }

  private void WireParent() {
    if(Parent != null) {
      Parent.SomeEvent += SomeHandler;
    }//if
  }

  private void UnwireParent() {
    if(Parent != null) {
      Parent.SomeEvent -= SomeHandler;
    }//if
  }
}

Здесь тот, кто выставляет Parent должен его же и обнулить, когда X становится не нужным. Можно реализовать в X IDisposabele:
public void Dispose() {
  Parent = null;
}

и тогда явно отпускать Parent не придётся. Тем более если таких ссылок на внешний мир может быть больше одной. В общем, Dispose — самое подходящее место, в котором объект может освободить ссылки [которые сам создал] на себя из внешнего мира что бы другие объекты могли жить без него.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re[4]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: TK модераторblogs.gotdotnet.ru
Дата: 08.02.10 11:54
Здравствуйте, _FRED_, Вы писали:

S>>Насчет сам создал — сам уничтожь согласен. Но вот отписка от событий в Dispose чем-то смущает...

_FR>А где ещё её делать, если подписываешься в конструкторе?

Надо завести собственный WeakEventManager и переложить подписку на него. Вызова Dispose никто не гарантирует.

_FR>Именно Dispose иесть самое подходящее место, как антипод конструктора.


А еще можно на C++ писать ;)
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 08.02.10 12:21
Здравствуйте, TK, Вы писали:

S>>>Насчет сам создал — сам уничтожь согласен. Но вот отписка от событий в Dispose чем-то смущает...

_FR>>А где ещё её делать, если подписываешься в конструкторе?

TK>Надо завести собственный WeakEventManager и переложить подписку на него.


С ним есть проблема — нельзя гарантировать, что к определённому моменту необходимые ресурсы будут освобождены (без, возможно, явного вызова некоего специального метода, который по сути будет тем же Dispose).

Протянуть его придётся на все уровни, где происходит подписка. Вариант, но только тогда, когда всё разрабатывается "с нуля". И то, если не требуется поддержка кода, созданного различными дизайнерами, которые умеют только "по-простому" работать с событиями.

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

TK>Вызова Dispose никто не гарантирует.


Его должен гарантировать тот, кто отвечает за disposable-объект.

_FR>>Именно Dispose иесть самое подходящее место, как антипод конструктора.

TK>А еще можно на C++ писать

Тогда, когда речь заходит о детерминированном освобождении ресурсов, и получается С++ с синтаксисом шарпа С помощью слабых ссылок и файнализаторов можно создать видимость автоматического управления ресурсами, но теряется определённость.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re[5]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: MozgChttp://nightcoder.livejournal.com
Дата: 08.02.10 12:27
Здравствуйте, TK, Вы писали:

TK>Вызова Dispose никто не гарантирует.


Не гарантирует, но должен гарантировать. Иначе ССЗБ.
Re[6]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: TK модераторblogs.gotdotnet.ru
Дата: 08.02.10 12:29
Здравствуйте, _FRED_, Вы писали:

TK>>Надо завести собственный WeakEventManager и переложить подписку на него.


_FR>С ним есть проблема — нельзя гарантировать, что к определённому моменту необходимые ресурсы будут освобождены (без, возможно, явного вызова некоего специального метода, который по сути будет тем же Dispose).


Одно другому не мешает.

_FR>Протянуть его придётся на все уровни, где происходит подписка. Вариант, но только тогда, когда всё разрабатывается "с нуля". И то, если не требуется поддержка кода, созданного различными дизайнерами, которые умеют только "по-простому" работать с событиями.


Так, "дизайнеры" себя отпиской обычно не утруждают...

_FR>Его должен гарантировать тот, кто отвечает за disposable-объект.


Да, такое сработает... но, это "вирусный" дизайн.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: TK модераторblogs.gotdotnet.ru
Дата: 08.02.10 12:35
Здравствуйте, MozgC, Вы писали:

TK>>Вызова Dispose никто не гарантирует.

MC>Не гарантирует, но должен гарантировать. Иначе ССЗБ.

Исходная тема начиналась с того, является ли требование !ССЗБ нормальным.
Лично мне кажется, что у ЗБ нет морального права чего либо требовать :)
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Sshurhttp://shurygin-sergey.livejournal.com
Дата: 08.02.10 12:41
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, TK, Вы писали:


TK>>Вызова Dispose никто не гарантирует.


MC>Не гарантирует, но должен гарантировать. Иначе ССЗБ.


А чем тогда необходимость вызывать Dispose у каждого IDisposable лучше delete ?
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[7]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: MozgChttp://nightcoder.livejournal.com
Дата: 08.02.10 12:53
Здравствуйте, Sshur, Вы писали:

S>А чем тогда необходимость вызывать Dispose у каждого IDisposable лучше delete ?


Тем что если Dispose все-таки не вызвать, то рано или поздно GC все-таки подчистит за ЗБ.
Re[8]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Sshurhttp://shurygin-sergey.livejournal.com
Дата: 08.02.10 12:58
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Sshur, Вы писали:


S>>А чем тогда необходимость вызывать Dispose у каждого IDisposable лучше delete ?


MC>Тем что если Dispose все-таки не вызвать, то рано или поздно GC все-таки подчистит за ЗБ.


Когда? При закрытии приложения? В том то и дело, что никогда он не подчистит, если есть активная ссылка
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[8]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: Lloyd 
Дата: 08.02.10 13:00
Здравствуйте, MozgC, Вы писали:

S>>А чем тогда необходимость вызывать Dispose у каждого IDisposable лучше delete ?


MC>Тем что если Dispose все-таки не вызвать, то рано или поздно GC все-таки подчистит за ЗБ.


Не подчистит. Event будет удерживать ссылку на объект и он никогда не будет собран GC.
Re[9]: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: MozgChttp://nightcoder.livejournal.com
Дата: 08.02.10 13:02
Здравствуйте, Lloyd, Вы писали:

L>Не подчистит. Event будет удерживать ссылку на объект и он никогда не будет собран GC.


Я говорил в общем. Объект предоставляющие event то когда-то уничтожится. Если это какой-то глобальный объект существующий все время жизни приложения, то да, косячокс.
Re: А нормально ли отписываться от событий в Dispose в избранное  новое    модер. 
От: MozgChttp://nightcoder.livejournal.com
Дата: 08.02.10 13:27
Ну а вообще вы что предлагаете?
Если не в Dispose() то где? В каком-то специальном методе типа UnwireEvents()? Так если вы Dispose() забываете вызвать, так уж что не будете вызывать UnwireEvents() — еще бОльший шанс
1 2 3 4