Адресат вызова создал исключение при Invoke map_dwgtrimobj

Автор Тема: Адресат вызова создал исключение при Invoke map_dwgtrimobj  (Прочитано 8763 раз)

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

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Никак не могу понять, из-за чего возникает ошибка. В процессе обработки полилиний я использую различные операции и команды, в частности, использую команду MAPTRIM:
Извините, вам запрещён просмотр содержимого спойлеров.

Так же мне приходится использовать команду MAPCLEAN, чтобы исправлять "неправильную" геометрию полилиний:
Извините, вам запрещён просмотр содержимого спойлеров.

Первая функция выполняется всего пару раз, чаще всего - всего один раз. А вот вторая функция выполняется по циклу десятки, а иногда и сотни раз.
И все это внутри одной главной транзакции.

В такой конфигурации, на четвертый раз выполнения начинают происходить странные вещи. Первые три раза команда (запускаемая из автокада) отрабатывает на отлично, а вот на четвертый раз она начинает пропускать некоторые полилинии, которые до этого отрабатывались без каких-либо проблем. На пятый раз появляется ошибка "Адресат вызова создал исключение" и идет ссылка на строку 34 из первой команды. После этого сам автокад начинает вести себя очень странно - объекты чертежа выбираются, но в свойствах "Ничего не выбрано". Выбор объектов не снимается после нажатия Esc. Приходится закрывать этот чертеж и открывать заново. Империческим путем я выяснил, что эта ошибка возникает только тогда, когда присутствует вызов команды MAPCLEAN. Я попытался заменить ее на OVERKILL:
Извините, вам запрещён просмотр содержимого спойлеров.

Но результаты превзошли все мои ожидания - уже на втором расчете возникают описанные выше проблемы, но уже с ссылкой на строку 6 из той же команды.

Причем все расчеты выполнялись при идентичных исходных данных, никаких отличий нет.

Я уже несколько дней ломаю голову, что же тут такое происходит и почти доломал ее )) Я смог придумать одно единственное более менее внятное объяснение - все манипуляции с полилиниями я провожу в одной открытой транзакции и в этой же транзакции я вызываю команды MAPCLEAN и OVERKILL. Возможно, их нужно вызывать вне открытой транзакции?

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

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

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Безусловно. Ты же понятия не имеешь что "у них под капотом".
Я очень боялся такого ответа - придется очень много переделывать (((

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Никак не могу понять, из-за чего возникает ошибка.
Сходу сказать сложно, стоит проверить:
1. как у тебя происходит выбор полилиний. Могут возникнуть нюансы с определением типа полилинии.

2. проверить кусок кода, после: "чтобы исправлять "неправильную" геометрию полилиний:"
List<Polyline> pls = new List<Polyline>(); ...судя по всему лишнее.

pline = (Polyline)trans.GetObject(ids_final[0], OpenMode.ForRead);
..непонятно, зачем открываешь, а затем закрываешь pline, лучше лишний раз не открывать, не зкарывать объекты. Возвращай id

pline = (Polyline)trans.GetObject(ids_final[0], OpenMode.ForRead);
...лучше заменить на
pline = trans.GetObject(ids_final[0], OpenMode.ForRead) as Polyline;
в первом случае, если вдруг в ids_final[0] id не полилинии, то произойдет исключение из-за приведения к неподходящему типу.

можно также до открытия объекта проверить, ids_final[0] а существует ли такой id в database.
Может Александр нас просветит, что будет, если вызывать trans.GetObjec(id... при некорректном id
И как правильно проверять id. Свойства id.IsValid достаточно?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
можно также до открытия объекта проверить, ids_final[0] а существует ли такой id в database.
Может Александр нас просветит, что будет, если вызывать trans.GetObjec(id... при некорректном id
И как правильно проверять id. Свойства id.IsValid достаточно?
Я так понимаю, что id выбираются пользователем из активного документа. Так что тут ничего плохого быть не может. При некорректном ObjectId trans.GetObjec(id...) может привести к чему угодно. Вплоть до Fatal Error.
Что касается ObjectId.IsValid, то из документации:
Цитировать
This function returns true if the object ID is associated with a database that is currently in memory. If the object ID is associated with a database that is no longer available (in other words, has been deleted), then false is returned.
Если какие-то примитивы в процессе работы могут удаляться (подозреваю, что MAPCLEAN это может делать), то желательно проверять еще и на IsErased.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
1. как у тебя происходит выбор полилиний. Могут возникнуть нюансы с определением типа полилинии.
...уточню, ты можешь выбирать по:
1. типу объекта Polyline
2. по dxf коду LWPOLYLINE
3. по имени класса AcDbPolyline
...в 99,9% случаев проблем нет с вариантом 1, но иногда это не так. И нужно пользоваться 3 вариантом. По второму варианту не подскажу.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
С выбором полилиний все просто - они создаются программно и, когда надо, записываются в БД чертежа.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Возможно, их нужно вызывать вне открытой транзакции?
Безусловно. Ты же понятия не имеешь что "у них под капотом".
К сожалению это не помогает ((( Я поставил цикл с выполнением команды MAPCLEAN после завершения транзакции и первые два раза расчет проходит успешно, а вот на третий - опять "Адресат вызвал исключение". Куда сейчас смотреть? Где искать ошибку? Подскажите, добрые люди! :)

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
В такой конфигурации, на четвертый раз выполнения начинают происходить странные вещи. Первые три раза команда (запускаемая из автокада) отрабатывает на отлично, а вот на четвертый раз она начинает пропускать некоторые полилинии, которые до этого отрабатывались без каких-либо проблем. На пятый раз появляется ошибка "Адресат вызова создал исключение" и идет ссылка на строку 34 из первой команды.

Империческим путем я выяснил, что эта ошибка возникает только тогда, когда присутствует вызов команды MAPCLEAN.

Попробуй:

1. А что делает с полилиниями MAPTRIM и MAPCLEAN? Обрезка и очистка?
Возможно в процессе работы получаются полилинии, слишком обрезанные? Например 2 точки, что не нравится функциям, или даже 1 или 0 точек!

2. Посмотри, что возвращает функция Application.Invoke(resbuf):
ResultBuffer result = null;
try
{
    result = Application.Invoke(resbuf);
...
if (result != null)
{
    TypedValue[] tpArr = result.AsArray();
А что, если функция возвращает не null, если ничего не находит?