По первой ссылке:Первые два случая, обозначенные Kean Walmsley требуют "ручного" вызова Dispose:
Temporary objects - such as those provided by Autodesk.AutoCAD.Geometry - which are never Database-resident
Temporary objects with the potential to be database-resident but which never actually get added to a Database
Несмотря на то, что транзакция (третий случай) автоматом вызывает Dispose для всех объектов, использовавшихся в её рамках, обозначенное "НО" заставляет задуматься о перестраховке:
There is no need to explicitly dispose of the objects managed by a Transaction (unless there is a failure between the time the object is created and when it is added to the transaction via AddNewlyCreatedDBObject(), of course).
Т.о. если объект был создан в рамках транзакции (не в блоке using) и после этого произошло необработанное исключение до того, как должен был быть вызван AddNewlyCreatedDBObject(), то в этом случае Dispose не будет вызван. Соответственно, имеет смысл каждый такой DBObject упаковывать в блок using - в этом случае Dispose будет вызван
гарантированно в любом случае.
Вот только не обозначен такой важный момент: если транзакция изначально упакована в using и произойдёт исключение, то в этом случае Dispose будет
гарантированно вызван для транзакции, а вот будет ли
в блоке using нашей транзакции, в этой ситуации, вызваны Dispose и для всех объектов, используемых в рамках данной транзакции? Т.е. вызываются ли методы Dispose объектов базы данных в коде метода TransactionDispose? Позднее, в третьей записи блога, Kean Walmsley всё же дал ответ на этот вопрос (см. ниже первую цитату в разделе "По третьей ссылке").
Вывод по первой ссылке я делаю такой: Dispose нужно вызывать самостоятельно, причём посредством упаковки каждого DBObject (а так же Document и Database) в блок using, дабы в случае исключения не пропустить ручной вызов Dispose.
По второй ссылке:Во второй обозначенной выше ссылке Kain Walmsley вроде как и написал чего-то, но по сути - никакой конкретики... Автор сообщает, что в составе API присутствуют некоторые общие ресурсы, и при вызове Dispose, эти ресурсы освобождаются без каких либо проверок на то, используется ли этот ресурс кем-то ещё... Насколько я понял, реализация кода такова, что при работе с общими ресурсами не используются счётчики ссылок, на основании значения которых в коде метода Dispose следовало бы определять, можно ли освобождать общий ресурс или же нет (хотя этот способ обозначен в любом букваре). Т.е. говоря по простому: код написан через задницу... Причём всех таких "весёлых" мест не знают даже разработчики Autodesk и, как я понял, исправляться это уже не будет "в целях обратной совместимости", как это нередко мотивируется. Единственное, чем нам могут помочь, это посоветовать "быть внимательными" (от оно чё, Михалыч...). Иными словами - флаг нам в руки и паровоз навстречу... Ну и "метод научного тыка": комментировать\раскомментировать Dispose...
Fenton’s assertion is that you really need to call Dispose() on all AutoCAD objects that you create yourself, unless they are managed by AutoCAD’s transaction system (i.e. you’ve passed responsibility across to AutoCAD by calling Transaction.AddNewlyCreatedDBObject()). Which means that while you don’t need to call Dispose() on objects such as the AutoCAD Editor or the active Document (and you really shouldn’t), you really should call Dispose() on various objects you’ve been used to letting the .NET garbage collector (GC) dispose of, such as those belonging to the Autodesk.AutoCAD.Geometry namespace.
Красным выделено то, что по мнению Kean Walmsley
является очевидным следствием предыдущего предложения. Вот только я, почему-то, в этом не вижу никакой логической связи... И почему нельзя вызывать Dispose для переменной, указывающей на активный документ? По выходе из метода переменная всё равно утилизируется. Помещаю Document и Database в блоки using (каждая в свой) и никаких проблем не наблюдаю. Может чего упустил?
Для Editor вызывать Dispose и не получится даже при сильном желании, поскольку данный класс не реализует IDisposable (во всяком случае в AutoCAD 2009).
So, to summarise… I don’t suggest people necessarily go back through and systematically call Dispose() on every geometry object they’ve ever created within their AutoCAD .NET code, but it’s certainly worth paying attention to this, moving forwards, as well as keeping in mind the problematic areas (such as BRep) should unexplained crash reports start to come in from users.
В первой ссылке Kean Walmsley рекомендовал вызывать Dispose для всех случаев, кроме работы в контексте транзакции (мол там это необязательно, ибо будет зачищено автоматом, при условии отсутствия исключений). А сейчас, получается, что "политика партии" резко изменила своё направление и теперь автор "не рекомендует возвращаться назад" к ручному вызову Dispose. "Так чего, Василий??? Дёргать, али не дёргать??? Ты уж определись..."(c).
По третьей ссылке:The short answer is that anything managed by a transaction – whether newly created and added to the transaction or opened by it – will be disposed of automatically by the transaction. So in general you shouldn’t even need a using block around such entities.
Вооот... Значит достаточно в блок using запихнуть только транзакцию и все объекты, оперируемые в её рамках будут зачищены в любом случае, даже при возникновении исключения (это радует).
Вывод:1. Транзакцию нужно инициализировать только в блоке using, тем самым снимая множество проблем со своей головы.
2. Объекты, прочтённые, изменённые или добавленные в рамках этой транзакции не нуждаются в Dispose, т.к. они будут автоматом вызваны в методе Dispose транзакции.
3. Все объекты, инициализированные не при помощи транзакции, должны зачищаться вручную, посредством размещения его в собственном блоке using.
4. Если автоматический Dispose какой-то переменной вызывает Fatal Error, значит для этой переменной не следует её инициализацию упаковывать в свой блок using. Это определяется только "методом научного тыка".