я так понимаю это что то связанное с потоками, потому что если вызывать только метод work (коммандой ss), то все работаетПравильно понимаешь. AutoCAD не потокобезопасный. Обращаться к его API безопасно можно только из основного потока.
Создание прогресс бара:Иногда стандартный прогресс-бар лучше не использовать. Например, когда к нему параллельно внутренние механизмы обращаются. Тогда можно сделать свой на любой вкус и цвет с помощью WPF. В общем случае, даже писать ничего не надо - примеры реализации есть в сети.Код - C# [Выбрать]
ProgressMeter pm = new ProgressMeter(); pm.SetLimit(max_len); pm.Start("текст"); System.Windows.Forms.Application.DoEvents();
В цикле для увеличения счетчика:Код - C# [Выбрать]
pm.MeterProgress(); System.Windows.Forms.Application.DoEvents();
Убрать прогресс бар после выполнения:Код - C# [Выбрать]
pm.Stop(); System.Windows.Forms.Application.DoEvents();
Создание прогресс бара:Не совсем так ;-)
Код - C# [Выбрать]
ProgressMeter pm = new ProgressMeter();
pm.SetLimit(max_len);
pm.Start("текст");
System.Windows.Forms.Application.DoEvents();
И все равно не понимаю как заставить работать прогресс бар.Делал тестовый пример, код пока не нашел, но примерно так:
Получатся у меня 2 потока - один это в AutoCAD, второй - прогресс бар. после запуска происходит следующее:
открывается окно с прогресс баром, выполняются все вычисления в цикле, а потом (по завершению цикла )
в прогресс бар передается последнее значение цикла. То есть он срабатывает, когда все вычисления закончены. Как заставить его работать синхронно с циклом?
4. Периодически выполняешь System.Windows.Forms.Application.DoEvents(); чтобы интерфейс обновлялся.А вот без этого, да, согласен - прогрессбар не обновляется, пока автокад не закончит работу с циклом.
Зачем второй поток?Я сделал некий тестовый проект и пока ни разу не применил.
вызов метода System.Windows.Forms.Application.DoEvents(); чтобы интерфейс обновлялся, одновременно как бы отменяет
using (App.DocumentLock docLock = doc.LockDocument()) и появляется куча разных ошибок в произвольных местах программы.
Как часто ты вызвал в коде Application.DoEvents()?После обработки каждого блока.
После того как я добавил проверку на время между вызовами аналога Application.DoEvents() и это время установил в от 0.1 до 0.5 секунды
не смотря на задержку в 1 сек, Автокад вываливается в фатал.1. Проверь, закомментируй все DoEvents(); будет ошибка или нет?
Я бы понял если бы ошибки были бы одинаковые или почти одинаковые, значит я где то накосячил с кодом, но тут полный раздрай.Похоже, что проблема где-то в другом месте.
На всякий случай Win7x64 и ADT 2017.Идея, конечно, из области догадок. Но может ADT в данном случае как-то вмешивается в работу прогрессбара? Возможно, что штатный прогрессбар в этот момент сам ADT задействует и возникает какой-то конфликт. У меня было такое, что я обрабатывал чертежи в фоне и пытался использовать этот штатный прогрессбар. В итоге в какой-то момент его "перехватывал" сам автокад и управление прогрессбаром из моего приложения прекращалось. Фатала не было но и не работало как надо. Мне пришлось переписать с использованием самописного погрессбара на основе немодального WPF окошка.
значит я где то накосячил с кодом
Вроде как, правильнее делать DoEvents после того, как прогрессметер "пнули", а не до этого, как в коде из #16.Вот результат
А, Привалов Дмитрий уже поправил это в коде из #17.
if (blockRef != null) //if (!id.IsNull)... 2. какая-то нереализованная проверка?В моем коде такого нет.
3. Выставляешь динамическое свойство. А существует ли оно и можно ли менять?Да, существует, да можно менять, да соответствует нужному типу, да укладывается в перечень разрешенных значений.
Что-то сложно как-то время вычисляется. Я так и не разобрался - есть там секунда или нет.Есть, на отладке специально перепроверял. Я сначала пытался через тики 0,1.. 0,5 сек использовать и только потом до 1 секунды дошел. Не помогло.
Сейчас тут AppContextOpenDocument(), ранее было создание базы и ReadDwg(), но теперешний вариант стабильнее и нужно что бы документ после завершения работы оставался открытым
Я на эту фигню более 30 часов убил и теперь просто принимаю как данность, лучше не использовать прогресс бар и DoEvents при работе с динамическими блокамиДумаю, тут проблема не в работе с динамическими блоками, а в том, что идёт работа с неактивным чертежом (если я правильно понял код).
А почему просто не открыть документ и не заблокировать?DocumentManager это объект класса DocumentCollection у него нет метода Open() и AppContextOpenDocument(путь_к_открываемому_файлу) это именно открытие файла в редакторе, по крайне мере я другого способа не знаю.
Cad.DocumentManager.Open(...);
Думаю, тут проблема не в работе с динамическими блоками, а в том, что идёт работа с неактивным чертежом (если я правильно понял код).Я так же подумал и переписал с ReadDwg() и работу в фоне, на AppContextOpenDocument() т.е. сознательно делаю и чертеж и базу активными. Результат не меняется.
Я так же подумал и переписал с ReadDwg() и работу в фоне, на AppContextOpenDocument() т.е. сознательно делаю и чертеж и базу активными. Результат не меняется.Я не увидел, а где чертёж делается активным? И если он активный, то зачем рабочую базу переключать?
Я не увидел, а где чертёж делается активным?AppContextOpenDocument() открывает и делает активным, вот тут есть пример кода и видяшка https://adn-cis.org/forum/index.php?topic=8979.0 . Загвоздка только в том, что AppContextOpenDocument не возвращает ничего и я был бы рад скормить MdiActiveDocument или CurrentDocument что то... но на нет и суда нет (это я про строчку 41 в коде Александра в указанной теме... и еще вот тут https://github.com/kevinzhwl/ObjectARXCore/blob/master/2015/inc/acdocman.h в строке 382 сказано, что открывает и переключает на нужный вид). Если просто закоментить отрисовку блока, то программа откроет документ в редакторе и можно сразу начинать с ним работать, т.е. он активный
И если он активный, то зачем рабочую базу переключать?Потому что идей почему оно падает не было и на всякий случай и базу переключаю, может и масло масленое.
This is AppContextRecoverDocument, a member of class DocumentCollection.Для чего, почему
ЗЫ.
Порадовало описание метода AppContextRecoverDocument():
Цитировать
This is AppContextRecoverDocument, a member of class DocumentCollection.
Для чего, почему
На всякий случай Win7x64 и ADT 2017.Вполне возможно, что это баг в этой версии или то, что это не чистый AutoCAD.
Может ещё что-то по мелочи подправить.Основная беда прогресс баров, это избыточный вызов методов Value += 1; и как следствие перерисовки прогресс баров, это дорогостоящая операция и DoEvents(); для отображения обновления.