几何尺寸与公差论坛

 找回密码
 注册
查看: 5116|回复: 0

【转帖】wpf多线程的一种解决方案

[复制链接]
发表于 2011-7-5 21:12:15 | 显示全部楼层 |阅读模式
http://www.haogongju.net/art/17932
  最近使用WPF来构建桌面程序,其中要求是:
   
  
   1. 界面与后台程序使用不同线程,以便在后台运行耗时计算时界面依然响应。
  
   2. 后台程序需要控制界面某些元素,如显示和修改值。
  
   3. 后台程序执行中,需要获取界面把某些用户输入,如用户输出某字符串来继续执行。
   
  
   
  
   然后开始设计,编码测试,过程如下:
  
   对于第1个要求,根据以前的编程经验(Qt,GTK...),果断使用System.Threading.Thread来Start一个线程,与WPF界面线程分开,嗯。
  
   对于第2个要求,使用DataBinding,把WPF界面的类的DataContext设置成给线程用的类里,绑定值,就很容易做到在第二个线程修改值直接反应到WPF的界面上。但对于切换界面(如修改MainWindow的Content给另外一个UserControl),搞得非常麻烦。想过通过绑定Visibility属性,添加IsVisibilityChange方法来做,效果都非常差。从MSDN看WPF多线程的例子http://msdn.microsoft.com/en-us/ ... 便更改WPF的元素了。
   
  
   接着第3个要求,考虑到.Net有ManualResetEvent(或者AutoResetEvent)这个很方便的类,果断写下这个UserInput类(暂时使用string来作为用户输入的表现)。
  
   然后在后台线程调用WaitInput,这下麻烦出来了,WPF界面线程也一起Block掉了。
  
   于是不停的修改代码,尝试网上搜索到的方法,均不能解决。 然后回头再仔细看MSDN关于WPF多线程的例子,每一个字都认真的读,发现Dispatcher是唯一的多线程可以修改WPF元素的类。那不知道我在另 外一个线程来调用Dispatcher.BeginInvoke来修改WPF元素可否?立即编写代码尝试。结果是可行的。最终程序结构如下:
  
   整个程序只有一个Window类,那就是从Window派生出来的MainWindow。定义若干UserControl与之相关的Presenter类(用于数据绑定和界面切换),并在MainWindow构造函 数里一一生成并绑定,所有的Presenter有Dispatcher属性,所有的Presenter有若干delegate用于数据绑定不能实现的操作 (定义一个基类即可),如更改MainWindow的Content,并在各个UserControl里定义相应的函数,赋于这些delegate,在 Presenter调用这些delegate的时候,使用Dispatcher.BeginInvoke来调用。初始Content为某一 UserControl。使用BackgroundWorker来启动后台线程,定义一个带ManualResetEvent的UserInput来给线 程得到WPF输入。
   
  
   这个后台线程就可以随时得到用户的输入,如用户想切换到某个特定界面, 后台线程得到这个输入后可以很方便的切换界面。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-4-27 19:04 , Processed in 0.034562 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表