REMOVEALLPROXY

Автор Тема: REMOVEALLPROXY  (Прочитано 124122 раз)

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

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Re: REMOVEALLPROXY
« Ответ #120 : 10-05-2016, 17:44:00 »
Сегодня прогнал на 2009х64. Похоже, я где-то что-то намудрил: команды выдают 0 объектов, а лисп-функции сообщают, что в файле 2 прокси объекта (если я все верно понимаю).
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #121 : 10-05-2016, 17:53:47 »
Сегодня прогнал на 2009х64. Похоже, я где-то что-то намудрил: команды выдают 0 объектов, а лисп-функции сообщают, что в файле 2 прокси объекта (если я все верно понимаю).
Ясно.

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #122 : 11-05-2016, 15:48:03 »
Подозреваю, что у тебя "шалит" Database.ReclaimMemoryFromErasedObjects. В моём коде он не используется.
Да, если закомментировать все её вызовы в коде, то проблемный файл обрабатывается нормально. Хотите сказать, что это не баг API, но либо я вызывал функцию не к месту, либо некорректный набор идентификаторов передаю в параметре?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #123 : 11-05-2016, 15:55:21 »
Хотите сказать, что это не баг API, но я вызывал функцию не к месту?
Интуитивно я предполагаю, что после вызова этого метода с чертежом лучше ничего больше не делать, а сразу его сохранить и закрыть.
Вообще этот метод добавили скорее всего для пакетной обработки файлов, чтобы противодействовать утечкам памяти. Но память освобождается, а ссылки на неё сохраняются пока база не закрыта. Это и приводит к непредсказуемым результатам.
Интересно, а в какой версии ты его проверял? Если мне не изменяет память, то этот метод появился в AutoCAD 2009.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #124 : 11-05-2016, 16:05:01 »
Но память освобождается, а ссылки на неё сохраняются пока база не закрыта. Это и приводит к непредсказуемым результатам.
Если это так, то это конкретный баг...
Интересно, а в какой версии ты его проверял? Если мне не изменяет память, то этот метод появился в AutoCAD 2009.
В нём и обнаружилась проблема. Соответственно в нём и тестировал.

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #125 : 11-05-2016, 16:14:59 »
Цитата: ObjectARX SDK 2009
This member function deletes the objects underneath the input object ids and performs some related cleanup.

The object ids in the input array must already be erased, and they should reside in the invoked database. Objects owned by the objects listed in the input array will be erased unless they already are, and their memory also reclaimed.

All deleted objects and memory will be restored upon undo, and re-deleted upon redo, by use of their DWG filing members.
Заменил везде это
Код - C# [Выбрать]
  1. ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased);
на такой вариант
Код - C# [Выбрать]
  1. ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased && n.IsResident);
и снова раскомментировал вызовы
Код - C# [Выбрать]
  1. db.ReclaimMemoryFromErasedObjects(ids);

Результат: дополнительная проверка не помогла и проблема снова наблюдается.

Вывод: похоже, что в AutoCAD реализация ReclaimMemoryFromErasedObjects является кривой и пользоваться этим методом не стоит. Добавлю директиву препроцессора и закомментирую для AutoCAD код, относящийся к использованию этого метода и добавлю соответствующие комментарии о том, почему это было сделано.

P.S.
Затем проверю, как вызов ReclaimMemoryFromErasedObjects на проблемном файле отработает в nanoCAD и BricsCAD (ZWCAD пока не настроил - сделаю это позже).

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #126 : 11-05-2016, 16:54:32 »
Дополнительная информация:

Использование ReclaimMemoryFromErasedObjects в AutoCAD 2016 не приводит к изчезновению примитивов и возникновению обозначенного выше окна с ошибкой (как это было в AutoCAD 2009). Однако последующий аудит находит кучу ошибок:
Цитировать
Total errors found 358 fixed 358

Т.о. метод ReclaimMemoryFromErasedObjects криво работает не только в AutoCAD 2009 , но и в AutoCAD 2016 (сильно подозреваю, что все промежуточные версии  AutoCAD - не исключение из этого правила).

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #127 : 11-05-2016, 17:09:48 »
В нём и обнаружилась проблема. Соответственно в нём и тестировал.
А в более свежих?
Если это так, то это конкретный баг...
Вопрос только чей.
Objects owned by the objects listed in the input array will be erased unless they already are, and their memory also reclaimed.
Вот это бы я выделил красным. При этом ссылки от других объектов на эти объекты становятся нарушенными (впрочем и без ReclaimMemoryFromErasedObjects тоже). Именно поэтому, когда я создавал REMOVEALLPROXY два десятка лет назад я понимал, что как минимум требуется _AUDIT таких чертежей. А возможно они будут невосстановимо убиты.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #128 : 11-05-2016, 17:43:02 »
Вот это бы я выделил красным.
Ну так это логично, что если зависимые от него объекты удалены, то и они будут подчищены.

Вопрос только чей.
Намекаете на то, что мой? Я помню, что вы выше "интуитивно предполагали", однако в документации я не вижу информации о том, в каких контекстах этот метод следует вызывать, а в каких нельзя. Я вижу описание метода. Контекст, в котором я использую ReclaimMemoryFromErasedObjects выглядит вполне уместно, особенно если учитывать, что:
Цитировать
All deleted objects and memory will be restored upon undo, and re-deleted upon redo, by use of their DWG filing members.
т.е. если я верно понял этот текст - операция, выполненная при помощи ReclaimMemoryFromErasedObjects может быть спокойно отменена или возобновлена командами undo и redo.

Цитата: Александр Ривилис
Именно поэтому, когда я создавал REMOVEALLPROXY два десятка лет назад я понимал, что как минимум требуется _AUDIT таких чертежей. А возможно они будут невосстановимо убиты.
Это всё здорово, только какое отношение это имеет к текущему поведению ReclaimMemoryFromErasedObjects? Я вызвал метод в соответствии с тем, как его использование документировано в SDK, передавая ему идентификаторы объектов, удовлетворяющих условию использования этого метода. На выходе получил поломанный документ. Поясните своё "Вопрос только чей." в данном контексте.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #129 : 11-05-2016, 17:59:49 »
Я вызвал метод в соответствии с тем, как его использование документировано в SDK, передавая ему идентификаторы объектов, удовлетворяющих условию использования этого метода. На выходе получил поломанный документ. Поясните своё "Вопрос только чей." в данном контексте.
1. Audit ты запускал в том же сеансе работы с dwg-файлом или сохранил, открыл его и выполнил Audit?
Если в одном сеансе, то понятно что ты не исправил все ссылки на удаляемые объекты. Это не то, что должен делать указанный тобой метод.
2. Этот метод просто освобождает память, занимаемую переданными объектами и теми объектами, которыми владеют переданные объекты. Но этот метод не анализирует базу в контексте того, какие еще могут быть ссылки на эти объекты. Если ты прочитаешь описание не только .NET-метода, а исходного ObjectARX метода, то увидишь, что там есть куча оговорок по поводу использования этого метода. В частности:
Цитировать
Some specialized object classes may require cleanup beyond the scope of this function. Such requirements cannot be anticipated in this function, so the developer who utilizes this function is advised to beware, and to thoroughly test the stability of the set of custom classes they anticipate to input to this function. They may have to wrap calls to this function in a function that performs additional cleanup for specific classes.
В данном случае тебе бы пришлось найти в базе все ссылки в других объектах на эти объекты (и все объекты, которыми они владеют и так далее по иерархии) и удалить эти ссылки или заменить их на что-то такое, что не приводит к ошибкам в структуре dwg-файла. Это очень и очень сложно. Так что остается уповать на корректность работы _AUDIT.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Re: REMOVEALLPROXY
« Ответ #130 : 11-05-2016, 18:09:42 »
Использование ReclaimMemoryFromErasedObjects в AutoCAD 2016 не приводит к изчезновению примитивов и возникновению обозначенного выше окна с ошибкой (как это было в AutoCAD 2009). Однако последующий аудит находит кучу ошибок:
Если не использовать ReclaimMemoryFromErasedObjects в 2016, аудит выдает 0 ошибок?

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #131 : 11-05-2016, 18:32:39 »
В данном случае тебе бы пришлось найти в базе все ссылки в других объектах на эти объекты (и все объекты, которыми они владеют и так далее по иерархии) и удалить эти ссылки или заменить их на что-то такое, что не приводит к ошибкам в структуре dwg-файла. Это очень и очень сложно. Так что остается уповать на корректность работы _AUDIT.
Т.е. в сухом остатке - лучше не использовать вызовы ReclaimMemoryFromErasedObjects в коде расширений.

Цитировать
Если не использовать ReclaimMemoryFromErasedObjects в 2016, аудит выдает 0 ошибок?
Я уже писал выше, что в этом случае аудит выдаёт 0 ошибок. В т.ч. и в 2016-м:
Цитировать
Command: NETLOAD
acad.proxy.R19.0.dll
© Andrey Bushman, 2016
 Commands:
proxy - get count of ProxyEntity and ProxyObject in the current Database.
xProxy - explode all proxy in the current Database.
rmProxy - remove all ProxyEntities and ProxyObjects in the current Database.
rmScales - remove all unused annotation scales in the current Database.

Command: AUDIT
Fix any errors detected? [Yes/No] <N>:
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 22300   objects audited
Auditing Entities Pass 2
Pass 2 22300   objects audited
Auditing Blocks
 466     Blocks audited
Auditing AcDsRecords
Total errors found 0 fixed 0
Erased 0 objects

Command: XPROXY
327 ProxyEntity items found.
327 ProxyEntity items exloded.
2700 new DBObjects created.
Count of 'HandOverTo' operations: 0.
Run the _AUDIT command with the _Y option, please.

Command: AUDIT
Fix any errors detected? [Yes/No] <N>:
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 24700   objects audited
Auditing Entities Pass 2
Pass 2 24700   objects audited
Auditing Blocks
 466     Blocks audited
Auditing AcDsRecords
Total errors found 0 fixed 0
Erased 0 objects

Command: RMPROXY
134 ProxyObject items found and removed.
Count of 'HandOverTo' operations: 0.
0 ProxyEntity items found and removed.
Count of 'HandOverTo' operations: 0.
Run the _AUDIT command with the _Y option, please.

Command: AUDIT
Fix any errors detected? [Yes/No] <N>:
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 24600   objects audited
Auditing Entities Pass 2
Pass 2 24600   objects audited
Auditing Blocks
 466     Blocks audited
Auditing AcDsRecords
Total errors found 0 fixed 0
Erased 0 objects

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: REMOVEALLPROXY
« Ответ #132 : 11-05-2016, 19:25:05 »
Т.е. в сухом остатке - лучше не использовать вызовы ReclaimMemoryFromErasedObjects в коде расширений.
Во всяком случае не в этом расширении. Если бы ты освобождал память из объектов, которые сам и создал и знаешь все их взаимосвязи, то этим методом можно было бы пользоваться.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #133 : 11-05-2016, 19:55:16 »
Во всяком случае не в этом расширении. Если бы ты освобождал память из объектов, которые сам и создал и знаешь все их взаимосвязи, то этим методом можно было бы пользоваться.
Ясно, спасибо.

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: REMOVEALLPROXY
« Ответ #134 : 12-05-2016, 18:30:03 »
На битбукете обновил версию исходников. Обозначенная выше ошибка исправлена, проект переделан так, чтобы при компиляции на выходе получался Bundle-пакет. Помимо аглицкого описания расширения присутствует и на русском. Откомпилированная версия так же обновлена (https://bitbucket.org/Andrey-Bushman/cadproxy/downloads ).