我知道不应该在多线程中调用/使用Autocad API。但是如何做一个不涉及任何特定Autocad调用/类型的多线程作业(在Autocad .Net插件中)?
情况是这样的: 1.一些CAD折线是通过API获取的,它们感兴趣的属性包含在客户类型中然后 2.在另一层中,针对这些客户类型进行了一些多线程计算。 3.应用程序客户类型通过Autocad API将结果写回CAD折线。
只有第二步是在多线程中完成的。
应用程序使用StartTransaction()方法获取Transaction对象。到目前为止,我还没有经历过多年的崩溃。但是现在我正在尝试使用StratOpenCloseTransasction()它会多次崩溃。特别是当调用Editor.Rengen()时它会崩溃,因为我认为它遍历数据库中的每个对象,也许有些被破坏了。我确实缩小了问题的范围,其中一个原因显然是这种多线程。
是否有任何理由说CAD在调用多线程时应该崩溃,尽管没有使用API?我可以安全地以这种方式使用多线程吗? 在处理对象时,StartTransaction()是否比StartOpenCloseTransaction更好地处理对象?因为我没有经历过崩溃。
非常感谢
答案 0 :(得分:4)
多线程的一大挑战是与主线程(AutoCAD线程)同步。当然,假设您没有将任何AutoCAD类型/数据/对象传递给另一个线程(只有纯.NET / C ++数据)。
了解风险后,您可以使用此PDF中描述的方法进行同步:http://aucache.autodesk.com/au2011/sessions/2526/class_handouts/v1_CP2526_Taget.pdf
以下是检查AutoCAD是否可以接收外部呼叫的主要代码:
bool isQuiescent(AcApDocument* pDoc = curDoc())
{
return ( (pDoc != NULL)
&& pDoc->isQuiescent()
&& ((pDoc->lockMode() == AcAp::kNotLocked) ||
(pDoc->lockMode() == AcAp::kNone))
&& (acedCommandActive() == 0) // no script or lisp is active
&& (acDocManager != NULL)
&& (acDocManager->inputPending(pDoc) == 0)
&& (::GetInputState() == 0)
);
}
答案 1 :(得分:3)
您为什么使用StartOpenCloseTransaction
?性能略有提升,但标准交易更安全。 OpenCloseTransaction的问题是没有人确切知道它是如何工作的。唯一的文件是:
的行为类似于Transaction对象,它包装对象的Open和Close方法,使得更容易关闭所有打开的对象,而不必显式关闭每个打开的对象。建议用于可能被称为未知次数的支持或实用程序函数,并在使用大多数事件处理程序时使用。
哪个不太清楚...
我只在事件处理程序中使用它,当需要启动事务时,对象处于不稳定状态。