Комментарии 27
честно говоря, до сих пор не понимаю, зачем в примере написали всю эту мешанину из флагов и параметров.
не советую внимать это и тем более использовать. юз-кейсов я пока не видел ни одного
не советую внимать это и тем более использовать. юз-кейсов я пока не видел ни одного
вникать — потому что в MS библиотеках так и сделано освобождение ресурсов. И если вы наследуетесь от какого либо класса, который есть в стандартной библиотеке, то должны знать, как вам, как потомку, предполагается освобождать ресурсы.
ну да, сделано. там много чего сделано. но с «Немного про освобождение ресурсов в .Net» это не связано.
но статью читать не советую. внимательный легко читатель найдет принципиальные ошибки в коде, из-за которых использовать эту мега-идею не получится.
при этом забыть вызвать base.Dispose(..) никто не мешает.
так что — имплементируйте IDisposable, пользуйтесь using, и всем будет хорошо.
но статью читать не советую. внимательный легко читатель найдет принципиальные ошибки в коде, из-за которых использовать эту мега-идею не получится.
при этом забыть вызвать base.Dispose(..) никто не мешает.
так что — имплементируйте IDisposable, пользуйтесь using, и всем будет хорошо.
>внимательный легко читатель найдет принципиальные ошибки в коде…
указание на ошибки только приветствуется — это же хорошо когда на них указывают. хуже когда про ошибки не говорят.
>… из-за которых использовать эту мега-идею не получится.
я сам предложенный класс мега-гениальным не считаю. он просто есть и он просто взят из msdn. вариантов его можно предложить разных и много. хуже, лучше — зависит от конкретной ситуации.
>при этом забыть вызвать base.Dispose(..) никто не мешает.
base.Dispose(...) таки забывают, согласен. иногда по забывчивости, а иногда — по не знанию.
>так что — имплементируйте IDisposable, пользуйтесь using, и всем будет хорошо.
С этим никто не спорит. Все верно.
Только я больше о другом: если тебе нужно наследовать от стандартного класса, например System.Windows.Forms.UserControl, то что в этом случае делать? Интерфейс IDisposable уже реализован в предке (на уровне System.ComponentModel.Component).
А очень хочется, чтобы твой контрол работал с unmanaged ресурсами. Например этот контрол должен уметь рендерить при помощи OpenGL и для этого ему надо уметь захватывать контекст устройства. И, соотвественно, уметь корректно его освобождать.
Перекрывать уже существующий метод Dispose — не вариант. И что тогда? Хотя про такое наследование у меня почти ничего и не написано… =(
Напишу следующий пост про наследование и Dispose =)
Но это уже не сегодня.
указание на ошибки только приветствуется — это же хорошо когда на них указывают. хуже когда про ошибки не говорят.
>… из-за которых использовать эту мега-идею не получится.
я сам предложенный класс мега-гениальным не считаю. он просто есть и он просто взят из msdn. вариантов его можно предложить разных и много. хуже, лучше — зависит от конкретной ситуации.
>при этом забыть вызвать base.Dispose(..) никто не мешает.
base.Dispose(...) таки забывают, согласен. иногда по забывчивости, а иногда — по не знанию.
>так что — имплементируйте IDisposable, пользуйтесь using, и всем будет хорошо.
С этим никто не спорит. Все верно.
Только я больше о другом: если тебе нужно наследовать от стандартного класса, например System.Windows.Forms.UserControl, то что в этом случае делать? Интерфейс IDisposable уже реализован в предке (на уровне System.ComponentModel.Component).
А очень хочется, чтобы твой контрол работал с unmanaged ресурсами. Например этот контрол должен уметь рендерить при помощи OpenGL и для этого ему надо уметь захватывать контекст устройства. И, соотвественно, уметь корректно его освобождать.
Перекрывать уже существующий метод Dispose — не вариант. И что тогда? Хотя про такое наследование у меня почти ничего и не написано… =(
Напишу следующий пост про наследование и Dispose =)
Но это уже не сегодня.
я как раз и сказал.
пару замечаний могу сказать сразу — то что в глаза бросилось. и это не связано напрямую со статьей
1. «private void Dispose(bool manual)»
должно быть virtual и скорее всего protected. без этого вся идея о наследовании становится бредом
2. private bool disposed = false;
я бы сделал protected. чтобы не делать ненужные копии в наследниках
3. //потому что в другом случае случае Dispose для них вызовет GC
касается вообще всего блока внутри «if (manual)»: смысла я не понял. потому что не понял с чего бы это коллектору вызывать какой-то там Dispose у каких-то managed ресурсов. и зачем делить на красных и белых? не диспознуто — диспозай. больше чем есть все равно не убить. если это может вызвать побочные эффекты — то лучше пусть вызывает. и чем больше и лучше — тем проще будет найти ошибки в архитектурных подходах
зы. а вот как раз var, я считаю, использовать корректно. я как бы за даже, потому что если F# продвинется, то пригодится.
зыы. ну минусуйте, подонки :) все равно правда восторжествует
пару замечаний могу сказать сразу — то что в глаза бросилось. и это не связано напрямую со статьей
1. «private void Dispose(bool manual)»
должно быть virtual и скорее всего protected. без этого вся идея о наследовании становится бредом
2. private bool disposed = false;
я бы сделал protected. чтобы не делать ненужные копии в наследниках
3. //потому что в другом случае случае Dispose для них вызовет GC
касается вообще всего блока внутри «if (manual)»: смысла я не понял. потому что не понял с чего бы это коллектору вызывать какой-то там Dispose у каких-то managed ресурсов. и зачем делить на красных и белых? не диспознуто — диспозай. больше чем есть все равно не убить. если это может вызвать побочные эффекты — то лучше пусть вызывает. и чем больше и лучше — тем проще будет найти ошибки в архитектурных подходах
зы. а вот как раз var, я считаю, использовать корректно. я как бы за даже, потому что если F# продвинется, то пригодится.
зыы. ну минусуйте, подонки :) все равно правда восторжествует
со 2м не согласен. нефиг наследнику влезать в логику предка.
а насчет 3 почитайте статью ссылку на которую я давал ниже. там все рассказано как и почему.
а насчет 3 почитайте статью ссылку на которую я давал ниже. там все рассказано как и почему.
2. да, давайте наплодим одних и тех же сущностей. к тому эе это могло бы стать частью контракта базового класса — раз уж от него предполагается наследоваться. get-only property я считаю лучше. и что значит не лезть, если мне предлагают именно с ней и ознакомится.
3. к сожалению, никакого «потому что» я там не увидел
3. к сожалению, никакого «потому что» я там не увидел
>касается вообще всего блока внутри «if (manual)»: смысла я не понял. потому что не понял с чего бы это коллектору вызывать какой-то там Dispose у каких-то managed ресурсов. и зачем делить на красных и белых? не диспознуто — диспозай.
пример не придуман, а взят из мсдн. не то что бы мсдн — последняя инстанция, но как «пожелания от MS» пойдет. Я могу только предполагать, зачем было решено разделить освобождение managed и unmanaged ресурсов.
Скорее всего дело тут в следующем. Как только был вызван Dispose из кода программы (а не во время работы сборщика мусора) предполагается «полная и прямо сейчас» очистка всех unmanaged ресурсов. А они могут быть не только в самом классе, но и внутри его managed член-переменных. Ждать, когда для них вызовется GC — не вариант. Поэтому для managed переменных тоже предполагается вызов Dispose — чтобы они тоже могли освободить свои unmanaged ресурсы.
пример не придуман, а взят из мсдн. не то что бы мсдн — последняя инстанция, но как «пожелания от MS» пойдет. Я могу только предполагать, зачем было решено разделить освобождение managed и unmanaged ресурсов.
Скорее всего дело тут в следующем. Как только был вызван Dispose из кода программы (а не во время работы сборщика мусора) предполагается «полная и прямо сейчас» очистка всех unmanaged ресурсов. А они могут быть не только в самом классе, но и внутри его managed член-переменных. Ждать, когда для них вызовется GC — не вариант. Поэтому для managed переменных тоже предполагается вызов Dispose — чтобы они тоже могли освободить свои unmanaged ресурсы.
кстати, насчет wgl. желаю, чтобы проблемы с dispose были единственными :)
Несколько раз на это напарывался.
Если наплюсуют кармы — перенесите сюда: habrahabr.ru/blogs/net/
Если наплюсуют кармы — перенесите сюда: habrahabr.ru/blogs/net/
Вот про GC.SuppressFinalize я не знал, спасибо.
Однако, мне очень сложно представить задачу, где так надо освобождать ресурсы, тк обычно используются уже готовые классы, в которых это всё уже реализовано.
Однако, мне очень сложно представить задачу, где так надо освобождать ресурсы, тк обычно используются уже готовые классы, в которых это всё уже реализовано.
Без обид, но есть более толковая статья: www.codeproject.com/KB/dotnet/idisposable.aspx
а использование var в качестве названия переменной это не пример говнокодерства?
исправлю, спасибо за замечание =)
Это пример лени)
а в чем разница между?
var i = 0 и int i = 0
(я то знаю, но просто у вас хочеться спросить)
var i = 0 и int i = 0
(я то знаю, но просто у вас хочеться спросить)
Что то с этим GC еще внимательнее нужно программировать и лучше все его тонкости понимать чем на обычном C++. «Захотела MS самодельную JVM, налабала фуфла и навязывает его изовсех сил». Происходит тоже самое, что помоему было с ActiveX,OLE, COM — некоторые возможности лепятся сбоку и ими невозможно пользоваться (MFC, CLR C++, ...)
проставлять флаг disposed = true лучше перед основным кодом освобождения ресурсов, иначе может быть проблема с многопоточным кодом. а финалайзеры — особая тема, не всегда следует их реализовывать по нескольким причинам. во-первых, существуют классы, которые требуют детерминированного уничтожения (например, используют другие managed-ресурсы, которые должны быть освобождены). в этом случае финалайзер не будет выполнять полезной работы и будет только мешать, создавая иллюзию нормальной работы и замедляя работу приложения (финалайзеры требуют особого обращения со стороны среды выполнения CLR .NET). кстати, в таких случаях в финалайзер можно засунуть метод оповещения о том, что объект не был освобожден принудительно, таким образом сигнализируя об утечке памяти / ресурсов. и этим мы элегантно превращаем «плохой» финалайзер в «хороший» и полезный. подробнее об этом я тоже планирую написать отдельную статью.
//
а вообще, ничего, спасибо вам за труд.
//
а вообще, ничего, спасибо вам за труд.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
О бедном Dispose замолвите слово