C# 令人困惑的API限制

C# 令人困惑的API限制,c#,multithreading,for-loop,revit,C#,Multithreading,For Loop,Revit,API不正式支持线程(见下文)或关闭活动文档的方法。也就是说,关闭活动文档的一个解决方法是调用 SendKeys.SendWait("^{F4}"); …从一个单独的线程。这很好,只是我需要循环打开和关闭几个文档。如果我将任何代码放在线程之后,它将在关闭前一个文档之前运行它。我尝试了许多标准线程回调方法,包括 Task.Factory.StartNew(() => ThreadPool.QueueUserWorkItem(new WaitCallback AutoResetEvent

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()
{
对于(int i=0;i<3;i++)
{
uiApp.OpenAndActivateDocument(TargetPath(i));
ThreadPool.QueueUserWorkItem(CloseDocProc);
//这里的任何代码都会打开下一个文档,而不会关闭最后一个文档
}            
}
public void CloseDocProc(对象状态信息)
{
SendKeys.SendWait(“^{F4}”);
//您可以在这里运行代码
}

问题在于线程,就像他们说的那样。使用任何回调方法,它都会在此时冻结。而且你只能在线程中执行有限的操作,它不会让我打开文档,无论发生什么

答案是使用单线程计时器

System.Windows.Forms.Timer;

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

不确定它是否可以完成此任务,但您可能可以使用此技术:

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

您需要if fact来封送对主线程的调用。实现这一点的最简单方法是在主线程上创建System.Windows.Forms.Control对象,并从关闭文档的单独线程调用其Invoke()


或者您也可以创造性地使用Idle事件…

在应用程序Idle事件处理程序中创建一个状态机,该处理程序与线程交互,并处理revit调用。

@topofsteel,请您解释一下您尝试使用AutoResetEvent.WaitOne时发生的情况。很明显,您需要等待,直到关闭ocProc在执行任何其他操作之前完成,并且,如您所说,如果必须从单独的线程调用关闭,则事件等待句柄听起来是一个不错的选项……但是,不清楚为什么不能同步运行。您的代码是否在AutoCad中运行,从而阻塞了主消息循环?您的整个代码体是否都可以使用be在单独的线程上运行,没有内部线程?
System.Windows.Forms.Timer;