令人困惑的API限制

时间:2012-08-20 20:00:39

标签: c# multithreading for-loop revit

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 个答案:

答案 0 :(得分:1)

问题在于线程,就像他们说的那样。使用任何回调方法,它会在那时冻结。并且你只能在线程中做有限数量的事情,它不会让我打开文档,无论如何!

答案是使用单线程计时器。

System.Windows.Forms.Timer;

每10秒左右调用一次Open()方法,并在计数器达到某一点时停止计时器并运行最后一段代码。

答案 1 :(得分:1)

不确定它是否可以解决问题,但您可以使用此技术:http://adndevblog.typepad.com/autocad/2012/06/use-thread-for-background-processing.html

适用于AutoCAD,但我认为它可以与Revit配合使用。 Revit API与AutoCAD一样,不支持多线程。您应该只从主线程调用API函数。

您需要将事实编组到主线程的调用。实现这一点的最简单方法是在主线程上创建一个System.Windows.Forms.Control对象,并从你关闭文档的单独线程中调用它的Invoke()。

或者您也可以以创造性的方式使用空闲事件......

答案 2 :(得分:0)

在app空闲事件处理程序中创建一个状态机,该处理程序与您的线程交互并处理revit调用。