Открытие объектов без использования транзакции.

Автор Тема: Открытие объектов без использования транзакции.  (Прочитано 40270 раз)

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

Оффлайн Константин Соков

  • ADN Club
  • **
  • Сообщений: 56
  • Карма: 0
Жаль, хотелось рыбку съесть и кости сдать. StartOpenCloseTransaction() в несколько раз шустрее чем StartTransaction(). Думал удастся ускорить приложение только поменяв StartTransaction() на StartOpenCloseTransaction()

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
StartOpenCloseTransaction() в несколько раз шустрее чем StartTransaction()
Ой ли? Зависит от конкретной ситуации.

Оффлайн Константин Соков

  • ADN Club
  • **
  • Сообщений: 56
  • Карма: 0
так-то оно так! Вот бы эту информацию в одном месте увидеть. Андрей, как продвигается идея с написанием книги по AutoCAD .Net API? Лично у меня она стала бы настольной.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Андрей, как продвигается идея с написанием книги по AutoCAD .Net API? Лично у меня она стала бы настольной.
Да я вроде как и не собирался этого делать. Опубликованный мною опрос лишь выявил, что интерес к книгам по данной теме стремится практически к нулю.

UPD
Кстати, Н.Н. Полещук недавно издал книгу по тематике программирования в AutoCAD. Там есть и глава по AutoCAD .NET API. Если бы позволял объём страниц и время, то можно было бы включить туда и материал по модульному, а так же автономному тестированию .NET плагинов AutoCAD с использованием Gallio и NUnit но в виду обозначенных ограничений материал остался за бортом.
« Последнее редактирование: 14-11-2014, 22:47:05 от Андрей Бушман »

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Там есть и глава по AutoCAD .NET API. Если бы позволял объём страниц и время, то можно было бы включить туда и материал по модульному, а так же автономному тестированию .NET плагинов AutoCAD с использованием Gallio и NUnit но в виду обозначенных ограничений материал остался за бортом.
А я вот, все надеюсь на статью по этой теме...

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
А я вот, все надеюсь на статью по этой теме...
Материал есть, всё никак "руки не дойдут" до его оформления.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Сейчас обнаружил ситуацию, в которой использование OpenCloseTransaction вместо Transaction помогло избавиться от ошибки:
Ситуация - открытие чертежа с внешними ссылками. Режим подгрузки внешних ссылок включен, это значит, что открытие чертежа идет по такому сценарию:
- создание Database открываемого чертежа
- создание Database копии чертежа-ссылки и копирование в нее объектов из чертежа-ссылки
и т.д.

Так вот, если во время этого копирования запросить NOD чертежа-ссылки, в обычной транзакции ловим исключение eNotFromThisDocument, а в ее эмуляции - нет исключения.
Интересно, почему так?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересно, почему так?
Думаешь без подготовленного тестового примера с этим можно разобраться? ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Загрузите этот код и попробуйте открыть чертеж "drawing.dwg".

Код - C# [Выбрать]
  1. using System;
  2.  
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6.  
  7. namespace ForAcadTests
  8. {    
  9.     public class XRefTest : IExtensionApplication
  10.     {
  11.         public void Initialize()
  12.         {            
  13.             Database.DatabaseConstructed += Database_DatabaseConstructed;
  14.         }
  15.  
  16.         void Database_DatabaseConstructed(object sender, EventArgs e)
  17.         {
  18.             Database db = sender as Database;            
  19.             db.BeginDeepClone += db_BeginDeepClone;
  20.         }
  21.  
  22.         void db_BeginDeepClone(object sender, IdMappingEventArgs e)
  23.         {            
  24.             Database
  25.                 origDb = e.IdMapping.OriginalDatabase;
  26.            
  27.             try
  28.             {
  29.                 using (Transaction tr = origDb.TransactionManager.StartTransaction())
  30.                 //using (Transaction tr = origDb.TransactionManager.StartOpenCloseTransaction())
  31.                 {
  32.                     DBDictionary nod = tr.GetObject(origDb.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
  33.                     Application.ShowAlertDialog(string.Format("NOD count: {0}", nod.Count));
  34.                     tr.Commit();
  35.                 }
  36.             }
  37.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  38.             {
  39.                 Application.ShowAlertDialog(string.Format("Exception: {0}", ex.Message));
  40.             }
  41.         }
  42.  
  43.         public void Terminate()
  44.         {
  45.             //throw new NotImplementedException();
  46.         }
  47.     }
  48. }

Кстати, если try-catch убрать, исключение произойдет тихо и бесшумно... При этом, подписки на события Database перестанут работать.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Замени:
Код - C# [Выбрать]
  1. Database origDb = e.IdMapping.OriginalDatabase;
на
Код - C# [Выбрать]
  1. Database origDb = sender as Database;
Думаю, что всё будет нормально... ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
В этом случае, конечно, код-то отработает нормально и без ошибок. :)
Только в sender будет база данных основного чертежа а не ссылки.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Тогда так:
Код - C# [Выбрать]
  1. void db_BeginDeepClone(object sender, IdMappingEventArgs e)
  2. {            
  3.     Database origDb = e.IdMapping.OriginalDatabase;
  4.    
  5.     try
  6.     {
  7.         using (Transaction tr = (sender as Database).TransactionManager.StartTransaction())
  8.         //using (Transaction tr = origDb.TransactionManager.StartOpenCloseTransaction())
  9.         {
  10.             DBDictionary nod = tr.GetObject(origDb.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
  11.             Application.ShowAlertDialog(string.Format("NOD count: {0}", nod.Count));
  12.             tr.Commit();
  13.         }
  14.     }
  15.     catch (Autodesk.AutoCAD.Runtime.Exception ex)
  16.     {
  17.         Application.ShowAlertDialog(string.Format("Exception: {0}", ex.Message));
  18.     }
  19. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Хм... Да, действительно, так работает... Но это же что получается, из транзакции одной базы получаем объект другой базы? Как такое возможно?  :o

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но это же что получается, из транзакции одной базы получаем объект другой базы? Как такое возможно?
А как возможно, что в событии одной базы (sender as Database) в качестве исходной фигурирует совсем другая база (e.IdMapping.OriginalDatabase) ? ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Ну тут все логично, на мой взгляд. Просто событие генерирует та база, в которую копируют. Ссылка на нее есть в e.IdMapping.DestinationDatabase. Вообще, хороший вопрос, какая из двух баз (исходная или целевая) генерирует это событие?