cad.net WPF嵌入技术2_将WPF嵌入到Acad08

将WPF嵌入到Acad08的时候,vs调试期间能成功,但是直接运行cad就不成功了.具体如下:

调试环境:

这个问题 测试版本为Acad2008,在Acad2014已经没有了..中间版本不清楚..

估计net3.5上都有..也就是08,09,10,11,12,13

 

问题如下:

利用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中显示。

 

 

 

 

(完)

posted @ 2020-12-12 18:04  惊惊  阅读(733)  评论(0编辑  收藏  举报