调试环境:
这个问题 测试版本为Acad2008,在Acad2014已经没有了..中间版本不清楚..估计net3.5上都有..
问题如下:
利用vs debug调试运行: 能看见我设置的小齿轮动起来了..
但是直接运行Acad2008的时候,则小齿轮无法运行,这个界面是卡死的..
出现bug的原因:
WPF必须新建一个线程来承载UI线程,
然后CAD2008用的是net3.5, 这个net版本没有很好地在runtime实现 Dispatcher.Run(); //WPF的UI线程(Dispatcher)
所以必须新开一个线程,之后就会占用这个当前线程来作为UI线程.
我实验了一下,不新建一个线程直接Dispatcher.Run(),抢夺了cad的主线程,导致WPF界面会动了,但是cad卡死了....
占用UI线程之前必须将WPF控件和嵌入动作包裹在线程内部再开始启动线程,否则会出现跨线程通讯....
与cad多线程通讯
但是即使如此,无可避免在WPF线程内的其他地方依然有和cad交互的跨线程通讯问题,怎么做呢?
WPF线程模型
见链接 https://www.cnblogs.com/Zhouyongh/archive/2009/08/31/1557126.html
精华摘录一段:
通常,WPF 应用程序从两个线程开始:一个用于处理呈现,一个用于管理 UI。 呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入、处理事件、绘制屏幕以及运行应用程序代码。 UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队。 Dispatcher 基于优先级选择工作项,并运行每一个工作项,直到完成。 每个 UI 线程都必须至少有一个 Dispatcher,并且每个 Dispatcher 都只能在一个线程中执行工作项。 这两段是MSDN上关于WPF线程模型的描述。 主要介绍了两个概念:一,WPF中线程一分为二,一个用于呈现(Render), 一个用于管理UI;二,在UI线程中,使用了一个名为Dispatcher的类帮助UI线程处理任务。 在WPF中,所有的WPF对象都派生自DispatcherObject,DispatcherObject暴露了Dispatcher属性用来取得创建对象线程对应的Dispatcher。 鉴于线程亲缘性,DispatcherObject对象只能被创建它的线程所访问,其他线程修改DispatcherObject需要取得对应的Dispatcher, 调用Invoke或者BeginInvoke来投入任务。 一个UI线程至少有一个Dispatcher来建立消息泵处理任务,一个Dispatcher只能对应一个UI线程。那么UI线程和Render线程又如何呢? 开篇提到,WPF线程一分为二,一个是UI线程,一个是Render线程。这两个被设计成分离的关系, 通过Channel(event)来进行通信。两者之间的数量关系是一个WPF进程只能有一个Render线程, 旦可以有大于等于一个的UI线程。通常情况下是一个UI线程,也就是一个Dispatcher,那么什么情况下需要建立多个呢? 大多情况下是不需要的,少数情况下,比如MediaElement,或者Host其他ActiveX控件,我们期望在其他线程中创建, 以提高性能。可以新建线程,在新线程中创建控件,并调用Dispatcher.Run启动Dispatcher。 这样主Window和新控件就处在不同线程中,两者间的通信可以使用VisualTarget连接视觉树或者使用D3DImage拷贝新控件到主Window中显示。
(完)