wpf高级编程,wpf使用winform控件
WPF启动后的两个线程:一个线程负责渲染并在后台运行。 另一个线程负责管理UI界面,主要负责接收收入、处理事件、绘制屏幕、执行APP应用程序代码或UI线程。
WPF中的每个接口和接口中的控件都从DispatcherObject类继承,DispatcherObject包含公共属性Dispatcher。 在初始化时,当前运行的主窗体和每个控件都会自动分配一个Dispatcher属性,并且指向同一个UI线程中的Dispatcher对象。
1.Dispatcher两个注册工作项的方法:
Invoke和BeginInvoke。 这两种方法都是通过调度请求来执行的。 其中Invoke是同步调用。 这意味着在UI线程实际执行完该请求之前不会返回。 BeginInvoke是异步的,很快就会返回。
2.Dispatcher的使用:
1 )解决“从非UI线程更新UI线程创建的对象”。
在一个子线程中直接访问或更新UI线程创建的对象时,将报告异常。 因为DispatcherObject对象只能由创建它的线程访问,所以其他线程要修改DispatcherObject,必须获取相应的Dispatcher,然后调用Invoke或BeginInvoke进行任务因此,此时可以使用Dispatcher的Invoke或BeginInvoke方法来完成UI线程上的控件更新。
例如,在另一个线程上更新Lable控件的内容
//新线程thread thread=new thread (updatelabletext ); thread.Start (; privatevoidupdatelabletext ((this.dispatcher.begininvoke ) dispatcherpriority.normal,(ThreadStart ) delegate ) ); )2)避免在. Dispatcher中处理花费时间的操作
Dispatcher优先对UI的工作队列进行排队。 如果UI线程上发生了耗时的操作,则Dispatcher工作队列中的其他项目可能需要等待,从而导致用户界面挂起。 因此,建议打开新线程以处理耗时的操作。 处理完成后,可以通过在UI线程的Dispatcher队列中注册工作项来通知UI线程的更新结果。 也可以说Dispatcher利用主线程进行任务优先排序,模拟多线程,所以其中实质上是单线程。
例如,对于合计显示的耗时操作,建议创建一个新线程以完成耗时的合计运算,并在得到合计结果后调用主线程Dispatcher来显示结果。
thread thread=new thread (更新标签文本; thread.Start (; privatevoidupdatelabletext ((string result=getsum ) ); //threadstart delegate )而不是Dispatcher的this.dispatcher.begininvoke (dispatcher priority.normal,)执行耗时的操作); }