Непонятные ограничения API

API официально не поддерживает многопоточность (см. Ниже) или способ закрытия активного документа. Тем не менее, работа вокруг закрытия активного документа состоит в том, чтобы позвонить...

SendKeys.SendWait("^{F4}");

... из отдельной темы. Это прекрасно работает, за исключением того, что мне нужно циклически открывать и закрывать несколько документов. Если я добавлю какой-либо код после потока, он запустится до закрытия предыдущего документа. Я пробовал ряд стандартных методов обратного вызова потоков, в том числе...

Task.Factory.StartNew(() =>

ThreadPool.QueueUserWorkItem(new WaitCallback

AutoResetEvent.WaitOne()

без удачи И Thread.Sleep() просто останавливает ошибку / сбой. У кого-нибудь есть какие-либо идеи.

Внутренние компоненты Revit используют многопроцессорную обработку только в нескольких отдельных изолированных местах. Ни одно из этих мест в настоящее время не охватывает код в Revit API или какую-либо его часть. Таким образом, Autodesk не рекомендует выполнять какие-либо вызовы Revit API изнутри одновременно, выполняя параллельные потоки. Может случиться так, что некоторая часть Revit API достаточно изолирована для того, чтобы иметь возможность успешно выполняться из такого многопоточного кода в тестовой среде, и это не следует рассматривать как гарантию того, что один и тот же исходный код будет функционировать для любого модели или ситуации, или что будущие изменения в Revit не приведут к прекращению работы этого кода ".

    public void OpenFile()
    {
        for (int i = 0; i < 3; i++)
        {
            uiApp.OpenAndActivateDocument(TargetPath(i));

            ThreadPool.QueueUserWorkItem(CloseDocProc);

            //any code here at all opens the next doc without closing the last
        }            
    }

    public void CloseDocProc(object stateInfo)
    {
        SendKeys.SendWait("^{F4}");

        //can run code here
    }

3 ответа

Решение

Проблема заключалась в том, что они как-то говорили. Используя любой из методов обратного вызова, он завис бы прямо в этой точке. И вы можете делать только ограниченное количество вещей в ветке, это не позволило бы мне открыть документ, несмотря ни на что!

Ответ заключался в использовании однопоточного таймера.

System.Windows.Forms.Timer;

вызывая мой метод Open() каждые 10 секунд или около того, останавливая таймер и выполняя последний бит кода, когда счетчик достигает определенной точки.

Не уверен, что это может сработать, но вы, возможно, можете использовать этот метод: http://adndevblog.typepad.com/autocad/2012/06/use-thread-for-background-processing.html

Это для AutoCAD, но я думаю, что он может работать с Revit. Revit API, как и AutoCAD, не поддерживает многопоточность. Вы должны вызывать функции API только из основного потока.

Вам нужно, чтобы факт маршал вызова в основной поток. Самый простой способ добиться этого - создать объект System.Windows.Forms.Control в главном потоке и вызвать его Invoke() из отдельного потока, в котором вы закрываете документ.

Или вы также можете использовать Idle Event творчески...

Создайте конечный автомат в обработчике события простоя вашего приложения, который взаимодействует с вашим потоком и обрабатывает вызовы revit.

Другие вопросы по тегам