ObjectId.GetObject()

Автор Тема: ObjectId.GetObject()  (Прочитано 3840 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ADSKАвтор темы

  • Administrator
  • Сообщений: 0
  • Карма: 2
ObjectId.GetObject()
« : 08-12-2014, 02:30:16 »

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Re: ObjectId.GetObject()
« Ответ #1 : 24-03-2020, 15:14:11 »
А нужно вызывать Dispose у полученного объекта?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: ObjectId.GetObject()
« Ответ #2 : 24-03-2020, 16:35:54 »
А нужно вызывать Dispose у полученного объекта?
Нет. Ведь это тоже самое, что открывать объект через транзакцию. Точнее через TransactionManager.TopTransaction.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Re: ObjectId.GetObject()
« Ответ #3 : 24-03-2020, 17:50:30 »
А почему этого не происходит на наглядном примере?
Код - C# [Выбрать]
  1.     public static class Commands
  2.     {
  3.         private static DBObject dbo;
  4.  
  5.         [CommandMethod(nameof(Test))]
  6.         public static void Test()
  7.         {
  8.             var doc = Application.DocumentManager.MdiActiveDocument;
  9.             LogDisposed(dbo, "До StartTransaction", doc);
  10.             using (var t = doc.TransactionManager.StartTransaction())
  11.             {
  12.                 dbo = doc.Database.BlockTableId.GetObject(OpenMode.ForRead);
  13.                 LogDisposed(dbo, "До Commit", doc);
  14.                 t.Commit();
  15.                 LogDisposed(dbo, "После Commit", doc);
  16.             }
  17.  
  18.             LogDisposed(dbo, "После Transaction.Dispose", doc);
  19.         }
  20.  
  21.         [CommandMethod(nameof(TestOpen))]
  22.         public static void TestOpen()
  23.         {
  24.             var doc = Application.DocumentManager.MdiActiveDocument;
  25.             using (dbo = doc.Database.BlockTableId.Open(OpenMode.ForRead))
  26.             {
  27.                 LogDisposed(dbo, "До Dispose", doc);
  28.             }
  29.  
  30.             LogDisposed(dbo, "После Dispose", doc);
  31.         }
  32.  
  33.         private static void LogDisposed(DBObject dbo, string msg, Document doc)
  34.         {
  35.             doc.Editor.WriteMessage($"\n{msg}: IsDisposed={dbo?.IsDisposed}");
  36.         }
  37.     }

Цитировать
Команда: TEST
До StartTransaction: IsDisposed=False
До Commit: IsDisposed=False
После Commit: IsDisposed=False
После Transaction.Dispose: IsDisposed=False
Не задиспозился объект  :-[

Цитировать
Команда: TESTOPEN
До Dispose: IsDisposed=False
После Dispose: IsDisposed=True
Задиспозился  ;D

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: ObjectId.GetObject()
« Ответ #4 : 24-03-2020, 18:22:39 »
До открытия транзакции и после её закрытия dbo вообще не имеет смысла. Поэтому твои логи совершенно не показательны.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: ObjectId.GetObject()
« Ответ #5 : 25-03-2020, 09:19:51 »
Я проверил. Похоже, транзакция действительно не вызывает метод Dispose у объекта при закрытии. Она только закрывает объект (в методе Commit):
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. namespace AcadTest2020
  7. {
  8.     public class TestTransaction
  9.     {
  10.         [CommandMethod("TestDisposeTransactionObject")]
  11.         public void RunCmd()
  12.         {
  13.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  14.             Editor ed = adoc.Editor;
  15.             Database db = adoc.Database;
  16.  
  17.             PromptEntityResult res = ed.GetEntity("\nSelect entity: ");
  18.             if (res.Status != PromptStatus.OK) return;
  19.  
  20.             ObjectId objId = res.ObjectId;            
  21.  
  22.             bool disposedIn, readEnabled;
  23.  
  24.             DBObject obj;
  25.  
  26.             using (Transaction tr = db.TransactionManager.StartTransaction())
  27.             {
  28.                 obj = tr.GetObject(objId, OpenMode.ForRead);
  29.  
  30.                 disposedIn = obj.IsDisposed;
  31.                 readEnabled = obj.IsReadEnabled;
  32.  
  33.                 tr.Commit();
  34.             }          
  35.  
  36.             ed.WriteMessage("\nIsDisposed. In transaction: {0}, after: {1}", disposedIn, obj.IsDisposed);
  37.             ed.WriteMessage("\nIsReadEnabled. In transaction: {0}, after: {1}", readEnabled, obj.IsReadEnabled);
  38.         }
  39.     }
  40. }
  41.  
Команда: TESTDISPOSETRANSACTIONOBJECT
Select entity:
IsDisposed. In transaction: False, after: False
IsReadEnabled. In transaction: True, after: False
Вопрос только в том, насколько это критично?

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Re: ObjectId.GetObject()
« Ответ #6 : 25-03-2020, 09:54:59 »
Да, казалось что это одно и тоже - закрытие и диспозинг объекта  ::)

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: ObjectId.GetObject()
« Ответ #7 : 25-03-2020, 10:02:06 »
У меня в голове тоже эти операции в одну слились. Причина понятна
Дано:
если транзакция - она управляет объектом
если не транзакция, значит обеспечиваем выполнение Dispose (через using или явно)
Вывод:
Значит Dispose - это закрытие. И транзакция выполняет эту операцию  :D

А получается, что Dispose и закрытие объекта - две разные операции. Просто Dispose выполняет в том числе и закрытие. А транзакция - только закрытие.