| 1 2 |
| Паттерн Dispose и финализатор | |
| От: | VladD2 админ | ||
| Дата: | 05.09.11 17:09 |
| У меня тут возник почти философский вопрос... Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. Ведь, в таком случае, все ресурсы имеют свои финализаторы и они один фиг будут вызваны. А сам паттерн Dispose, как бы, предлагает не вызвать Dispose для управляемых объектов из финализатора. Наличие финализатора автоматически продвигает объекты в седующее поколение. Плюс увеличение очереди финализации не ускоряет производительности. Так не лучше ли не реализовывать финализатор для объектов не управляющих неуправляемыми ресурсами? Это, конечно, приводит к тому, что придется объявлять финализатор в классах-наследниках таких "безфинализаторных" объектах реализующих паттерн Dispose. Но ведь это как раз не проблема. В общем, вопроса как такового нет. Просто хочется получить конструктивную критику моих размышлений. Прав ли я? И, если не прав, то в чем я заблуждаюсь? |
| Re: Паттерн Dispose и финализатор | |
| От: | G2 | ||
| Дата: | 05.09.11 17:49 |
| Здравствуйте, VladD2, Вы писали: VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. AFAIK, стратегия такая, что реализовывать Finalize и Dispose нужно, только если сам тип должен освободить unmanaged ресурсы, которые он сам же и выделял. Если объект выделяет память только под disposable managed ресурсы, то реализовывать IDisposable не нужно. Улыбаемся и машем :-) |
| Re: Паттерн Dispose и финализатор | |
| От: | G2 | ||
| Дата: | 05.09.11 17:52 | ||
| Оценка: | +1 | ||
| Здравствуйте, VladD2, Вы писали: VD>У меня тут возник почти философский вопрос... VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. AFAIK, стратегия такая, что реализовывать Finalize и Dispose нужно, только если сам тип должен освободить unmanaged ресурсы, которые он сам же и выделял. Если объект выделяет память только под disposable managed ресурсы, то реализовывать Finalize не нужно. Улыбаемся и машем :-) |
| Re: Паттерн Dispose и финализатор | |
| От: | Lloyd | ||
| Дата: | 05.09.11 17:58 | ||
| Оценка: | 48 (1) +1 | ||
| Здравствуйте, VladD2, Вы писали: VD>В общем, вопроса как такового нет. Просто хочется получить конструктивную критику моих размышлений. Прав ли я? И, если не прав, то в чем я заблуждаюсь? Прав. Вот комментарий из примера в msdn: http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx |
| Re[2]: Паттерн Dispose и финализатор | |
| От: | VladD2 админ | ||
| Дата: | 05.09.11 18:12 |
| Здравствуйте, G2, Вы писали: G2>AFAIK, стратегия такая, что реализовывать Finalize и Dispose нужно, только если сам тип должен освободить unmanaged ресурсы, которые он сам же и выделял. Если объект выделяет память только под disposable managed ресурсы, то реализовывать IDisposable не нужно. Не верная, у тебя, стратегия. Dispose реализуется для освобождения любых ресурсов. И об этом везде, и довольно доходчиво, сказано. Объект может банально отписываться от событий или закрывать несколько ресурсов которыми он владеет. Вот на счет Finalize согласен. |
| Re[2]: Паттерн Dispose и финализатор | |
| От: | VladD2 админ | ||
| Дата: | 05.09.11 18:14 |
| Здравствуйте, Lloyd, Вы писали: L>Прав. Вот комментарий из примера в msdn: L> L>http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx Больно убого (и по разному) они его описывают. Есть прмеры, где финализатор запихивается в базовый класс, и стало быть, поддерживаются даже, если анменеджед-ресурсов нет (просто ради того что они могут появиться в наследнике). |
| Re: Паттерн Dispose и финализатор | |
| От: | hardcase | ||
| Дата: | 05.09.11 18:16 | ||
| Оценка: | 10 (2) | ||
| Здравствуйте, VladD2, Вы писали: VD>У меня тут возник почти философский вопрос... Возможно эта статья поможет. |
| Re: Паттерн Dispose и финализатор | |
| От: | TK модератор | ||
| Дата: | 05.09.11 18:18 |
| Здравствуйте, VladD2, Вы писали: VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. Статья на MSDN еще со времен первого фреймворка. Для неуправляемых ресурсов есть SafeHandle. VD>В общем, вопроса как такового нет. Просто хочется получить конструктивную критику моих размышлений. Прав ли я? И, если не прав, то в чем я заблуждаюсь? По хорошему, у объекта с финализатором в конструкторе должен быть GC.SuppressFinalize(this), а реальная регистрация в очереди должна быть в методе типа SetResource(...) Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят. |
| Re[3]: Паттерн Dispose и финализатор | |
| От: | Lloyd | ||
| Дата: | 05.09.11 18:18 | ||
| Оценка: | +1 | ||
| Здравствуйте, VladD2, Вы писали: VD>Не верная, у тебя, стратегия. Dispose реализуется для освобождения любых ресурсов. И об этом везде, и довольно доходчиво, сказано. Объект может банально отписываться от событий или закрывать несколько ресурсов которыми он владеет. Он поправился ниже. |
| Re[2]: Паттерн Dispose и финализатор | |
| От: | TK модератор | ||
| Дата: | 05.09.11 18:26 | ||
| Оценка: | 2 (1) | ||
| Здравствуйте, G2, Вы писали: G2>AFAIK, стратегия такая, что реализовывать Finalize и Dispose нужно, только если сам тип должен освободить unmanaged ресурсы, которые он сам же и выделял. Если объект выделяет память только под disposable managed ресурсы, то реализовывать Finalize не нужно. CriticalFinilizerObject есть одно из следствий того, что в финализаторах бывает нужно "освобождать" другие managed объекты. Типичный пример — буферизированный поток. Никаких unmanaged ресурсов у него может и не быть но, при этом может потребоваться сбросить буфер даже в случае "потери" объекта. Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят. |
| Re: Паттерн Dispose и финализатор | |
| От: | rm822 | ||
| Дата: | 06.09.11 05:14 |
| VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. VD>Ведь, в таком случае, все ресурсы имеют свои финализаторы и они один фиг будут вызваны. Да — нужно, нет не будут(по крайней мере не будут вызываны вовремя).
где-то в недрах системы есть синглтон реализующий подписку на WinLogon события. после вызова m_ctrl.SubscribeOnWinlogonEvents, остается ссылка на m_ctrl которая не будет освобождена. Рвать эту связь придется и в MyForm.Dispose и в MyForm.Finalize ... << RSDN@Home 1.1.4 stable SR1 rev. 568>> |
| Re[2]: Паттерн Dispose и финализатор | |
| От: | TK модератор | ||
| Дата: | 06.09.11 05:17 |
| Здравствуйте, rm822, Вы писали: R>где-то в недрах системы есть синглтон реализующий подписку на WinLogon события. R>после вызова m_ctrl.SubscribeOnWinlogonEvents, остается ссылка на m_ctrl которая не будет освобождена. R>Рвать эту связь придется и в MyForm.Dispose и в MyForm.Finalize В чем смысл разрывания связи в Finalize? Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят. |
| Re[3]: Паттерн Dispose и финализатор | |
| От: | rm822 | ||
| Дата: | 06.09.11 05:38 |
| TK>В чем смысл разрывания связи в Finalize? представь что MyForm — популярная формочка, которой пользуется еще 30 человек в компании. Кто-нибудь обязательно не напишет using мы не можем гарантировать вызов MyForm.Dispose, а раз не можем — придется подстраховаться в Finalize, иначе будет утечка ресурсов ... << RSDN@Home 1.1.4 stable SR1 rev. 568>> |
| Re: Паттерн Dispose и финализатор | |
| От: | SergeyT. rsdn | ||
| Дата: | 06.09.11 06:58 | ||
| Оценка: | 74 (3) +2 | ||
| Здравствуйте, VladD2, Вы писали: VD>У меня тут возник почти философский вопрос... VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. VD>В общем, вопроса как такового нет. Просто хочется получить конструктивную критику моих размышлений. Прав ли я? И, если не прав, то в чем я заблуждаюсь? ИМХО следующее. Камрад Рихтер, как и некоторые примеры MSDN-а приводят не самые лучшие примеры. Каноническая реализация Disposable-паттерна следующая (это все знают, но так обсуждать легче):
Идея этого паттерна сводится к тому, что у нас могут появится наследники, у который появятся голые неуправляемые ресурсы, поэтому многие прикладные программисты его слепо копи-пастят, а иногда, не понимая четко все его принципы оставляют финализатор, даже есть у текущего класса нет неуправляемых ресурсов. При этом ветка else в методе Dispose(bool) всегда остается пустой. При этом в абсолютно подавляющем большинстве случаев наследников с неуправляемыми ресурсами так никогда и не появляются. Получается, что люди используют паттерн "оптимизированный" для довольно узкого случая, а в наиболее распространенном случае код содержит избыточные условия и хуже читается. Кроме того, даже если у кого-то возникает потребность в оболочке над неуправляемым ресурсом, то здравый смысл, а также всякие SRP подсказывают, что разумно создать отдельный wrapper над ним, и пользоваться уже этим wrapper-ом, а не распихивать неуправляемыми ресурсами по разным классам. RAII идиому еще никто не отменял и настолько сильно смешивать обязанности классов, когда в иерархии наследников базовый класс будет содержать управляемые ресурсы, а наследник добавит еще парочку неуправляемых, кажется, по меньшей мере? неразумным. Все это я к тому, что кейс, когда наследник все же добавит неуправляемый ресурс, хотя и является возможным, но он является по меньшей мере сомнительным дизайн-решением. Отсюда ИМО, оставить финализаторы только wrapper-ам, реализующим RAII, остальным юзать только управляемые ресурсы, а посему — забить на финализаторы. |
| Re: Паттерн Dispose и финализатор | |
| От: | Sinix | ||
| Дата: | 06.09.11 07:03 |
| Здравствуйте, VladD2, Вы писали: VD>Нужно (ну, хотя бы в каких-то случаях), при реализации паттерна Dispose, реализовывать финализатор, если объект не содержит ссылок на неуправляемые ресурсы. По-моему, только в очень редких случаях. Сам использовал пару раз для аварийного удаления временных файлов, но там ситуация была из разряда "жить захочешь — и не так раскорячишься". |
| Re[2]: «Disposable Design Principle» vs. «IDisposable code p | |
| От: | Qbit86 | ||
| Дата: | 06.09.11 07:14 |
| Здравствуйте, SergeyT., Вы писали: ST>Отсюда ИМО, оставить финализаторы только wrapper-ам, реализующим RAII, остальным юзать только управляемые ресурсы, а посему — забить на финализаторы. По ссылке Автор: hardcase hardcase это и написано. Там ещё всякое интересное написано, про Constrained Execution Region, GC.KeepAlive и SafeHandle.Дата: 05.09.11 Глаза у меня добрые, но рубашка — смирительная! |
| Re[4]: Паттерн Dispose и финализатор | |
| От: | TK модератор | ||
| Дата: | 06.09.11 08:20 |
| Здравствуйте, rm822, Вы писали: R>представь что MyForm — популярная формочка, которой пользуется еще 30 человек в компании. Кто-нибудь обязательно не напишет using R>мы не можем гарантировать вызов MyForm.Dispose, а раз не можем — придется подстраховаться в Finalize, иначе будет утечка ресурсов Вы точно правильно себе представляете что такое форма и в какой момент вызывается Finalize? Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят. |
| Re[5]: Паттерн Dispose и финализатор | |
| От: | rm822 | ||
| Дата: | 06.09.11 08:50 | ||
| Оценка: | 1 (1) +1 | ||
| TK>Вы точно правильно себе представляете что такое форма и в какой момент вызывается Finalize? да. Если есть что сказать — говори прямо, а не ходи вокруг да около с неуместными намеками на некомпетентность собеседника. ... << RSDN@Home 1.1.4 stable SR1 rev. 568>> |
| Re: Паттерн Dispose и финализатор | |
| От: | Neco | ||
| Дата: | 06.09.11 08:53 |
| Здравствуйте, VladD2, Вы писали: VD>Это, конечно, приводит к тому, что придется объявлять финализатор в классах-наследниках таких "безфинализаторных" объектах реализующих паттерн Dispose. Но ведь это как раз не проблема. но это ведь может стать проблемой — пользователь-программист должен не забыть объявить финализатор. наличие финализатора в базовом классе делает неправильное использование менее вероятным, мне кажется. а то переопределит Dispose и пока (я, например, так бы и поступил). кстати, а какие примеры реальной необходимости объявлять IDisposable при отсутствии неуправляемых ресурсов? Например, тот же TextReader зачем надо было делать IDisposable? Разве это не ответственность того, кто создаёт реально Disposable наследника — вызывать Dispose и т.п.? значит он тип должен знать? всю ночь не ем, весь день не сплю — устаю |
| Re[6]: Паттерн Dispose и финализатор | |
| От: | TK модератор | ||
| Дата: | 06.09.11 09:03 | ||
| Оценка: | +1 | ||
| Здравствуйте, rm822, Вы писали: TK>>Вы точно правильно себе представляете что такое форма и в какой момент вызывается Finalize? R>да. Если есть что сказать — говори прямо, а не ходи вокруг да около с неуместными намеками на некомпетентность собеседника. Какие намеки? Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят. |
| 1 2 |