Непонятные ограничения 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.