Можно ли работать с Entity получив из функции

Автор Тема: Можно ли работать с Entity получив из функции  (Прочитано 9623 раз)

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

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

  • ADN
  • *
  • Сообщений: 2468
  • Карма: 698
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Если на каждый Open не будет Close - гарантированный Fatal Error.
Помимо этого, есть еще 2 проблемы, которые могут возникнуть при использовании Open:
1. Если объект ранее был открыт на запись, или на чтение 255 раз - исключение. Вы как-то сами мне это подсказали ;). Вот как проверить это перед открытием объекта? У транзакции нет таких ограничений. Я так понимаю, что она не переоткрывает объект, а находит его среди открытых и возвращает ссылку на него.
2. А что будет в Вашем примере, если открытый объект не удастся привести к Entity? Объект откроется, но не закроется, как я понимаю.

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

  • Administrator
  • *****
  • Сообщений: 13196
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Если объект ранее был открыт на запись, или на чтение 255 раз - исключение. Вы как-то сами мне это подсказали ;). Вот как проверить это перед открытием объекта?
Если использовать using, то никогда в такую ситуацию не попадёшь. Разве что сделаешь 255 вложенных using с одним и тем же ObjectId.
2. А что будет в Вашем примере, если открытый объект не удастся привести к Entity? Объект откроется, но не закроется, как я понимаю.
Нужно конечно проверить, но думаю что всё будет нормально, так как ObjectId.Open возвращает DBObject, а он тоже в конечном итоге происходит от DisposableWrapper. Соответственно вызовется его метод Dispose, соторый равносилен Close. Так что всё будет нормально.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2468
  • Карма: 698
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Если использовать using, то никогда в такую ситуацию не попадёшь.
Не поверите, уже столкнулся. Происходит обращение к объекту, который был открыт на редактирование то ли самим автокадом, то ли другим методом.
Нужно конечно проверить, но думаю что всё будет нормально
Как я понимаю, Ваш код эквивалентен этому:
Код - C# [Выбрать]
  1. Entity ent = id.Open(...) as Entity;
  2. using (ent)
  3. {
  4.  
  5. }
  6.  
А ent = null, если id передан не для Entity. И ссылка на открытый объект в using не передастся.

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

  • Administrator
  • *****
  • Сообщений: 13196
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Не поверите, уже столкнулся. Происходит обращение к объекту, который был открыт на редактирование то ли самим автокадом, то ли другим методом.
Теоретически возможно. Но тут речь не про 255 "на чтение" с дополнительной попыткой открыть "на чтение", а открытый "на запись" и вторая попытка открытия. А это согласись разные вещи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13196
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Как я понимаю, Ваш код эквивалентен этому:
А я думаю, что не эквивалентен. Тут или очень хорошо знать теорию, или экспериментировать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2468
  • Карма: 698
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Но тут речь не про 255 "на чтение" с дополнительной попыткой открыть "на чтение", а открытый "на запись" и вторая попытка открытия. А это согласись разные вещи.
Да я согласен, конечно :) Я же не с целью поспорить, а просто хочу предупредить о возможной опасности.
Тут или очень хорошо знать теорию, или экспериментировать.
Проверил вот таким кодом, в 19 строке исключение, что объект открыт на запись:
Код - C# [Выбрать]
  1. public class DBObjectsTest
  2. {
  3.     /// <summary>
  4.     /// Работа с объектами БД чертежа
  5.     /// </summary>
  6.     [CommandMethod("DBObjectsTest")]
  7.     public void DBObjectsTestRun()
  8.     {
  9.         Document adoc = Application.DocumentManager.MdiActiveDocument;
  10.         Database db = adoc.Database;
  11.  
  12.         ObjectId id = db.CurrentSpaceId;
  13.  
  14.         using (Entity ent = id.Open(OpenMode.ForWrite) as Entity)
  15.         {
  16.  
  17.         }
  18.  
  19.         using (DBObject obj = id.Open(OpenMode.ForRead))
  20.         {
  21.  
  22.         }
  23.     }
  24. }
  25.  

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

  • Administrator
  • *****
  • Сообщений: 13196
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Значит я не прав и приведение следует делать внутри using если не уверен в типе объекта.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение