ObjectId.IsEffictivelyErased = true у трубы или колодца.

Автор Тема: ObjectId.IsEffictivelyErased = true у трубы или колодца.  (Прочитано 3805 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Здравствуйте!
Моё .NET-приложение создаёт несколько труб и колодцев в Civil 3D 2020. Они создаются в цикле по заранее вычисленным параметрам. Сперва - трубы, потом, на их концах, - колодцы. А потом трубы цепляются к колодцам. Количество - несколько десятков.
И, почему-то, некоторые из них (2-3 штуки) после создания имеют свойство ObjectId.IsEffictivelyErased = true. При этом, объекты на чертеже есть. при попытке посмотреть их свойства через
ARXDBG выскакивает ошибка "ARX ERROR" (см. картинку). Но потом всё равно открывается окно с данными об объекте. Притом, если повторять создание несколько раз, то каждый раз объекты с таким свойством возникаю рандомно. То есть, в первый раз - одни трубы-колодцы, в следующий - другие. Иногда вообще без этого отрабатывает.
Если чертёж сохранить и открыть заново - эти объекты "чинятся", ObjectId.IsEffictivelyErased становится равно false.
В связи с этим, у меня вопросы:
В чём теоретически может быть проблема?
Даёт ли какую-то полезную информацию это сообщение об ошибке ARX?
Может не стоит совсем обращать внимание на значение ObjectId.IsEffictivelyErased и спокойно продолжать открывать объект на чтение-запись в коде .NET?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Даёт ли какую-то полезную информацию это сообщение об ошибке ARX?
Да. Объект был открыт максимальное количество раз (255) и при этом не был закрыт. Копай в эту сторону.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Ох ничего себе! Да, это так просто нельзя оставлять... Спасибо! Буду искать причину.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ох ничего себе! Да, это так просто нельзя оставлять... Спасибо! Буду искать причину.
Теоретически это может быть баг в AutoCAD/Civil 3D, но конечно нужно в первую очередь проверять у себя в коде.
Причем с обычной транзакцией это происходить не должно - или ObjectId.Open, или эмуляция транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
или ObjectId.Open, или эмуляция транзакции
Да, это у меня есть. Буду проверять.

Отмечено как Решение Дмитрий Загорулькин 22-11-2019, 18:40:32

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Как оказалось, работу нарушал с виду довольно безобидный метод:
Код - C# [Выбрать]
  1. static T GetOrOpenForWrite<T>(Transaction tr, ObjectId id)where T : DBObject
  2. {
  3.     using (DBObjectCollection allTrObjects = tr.GetAllObjects())
  4.     {
  5.         return allTrObjects
  6.             .Cast<DBObject>()
  7.             .FirstOrDefault(item
  8.                 => item is T dbObject
  9.                 && dbObject.Id.Equals(id)
  10.                 && dbObject.IsWriteEnabled) as T
  11.             ?? tr.GetObject(id, OpenMode.ForWrite) as T;
  12.     }
  13. }
  14.  
Идея его такая. Есть довольно много ObjectId труб и колодцев. Они берутся попарно и с ними производятся манипуляции: открытие, проверка, если проверка пройдена - модификация. И чтобы не открывать дважды один и тот же объект, ищем - не был ли он открыт ранее в этой транзакции? Если да, то берём из списка объектов, открытых в транзакции. Если нет - открываем объект этой транзакцией. Хотя, по сути, как я понимаю, это - уже извращение. Потому что при повторном открытии объекта транзакцией никакого криминала не возникает. Я так понимаю, всё то что в этом методе, транзакция делает внутри себя при открытии объекта. Но мне почему-то захотелось сделать это явно...  :-X
При замене вызова этого метода на простое открытие объекта транзакцией проблема пропадает.