首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

深入显出GUI线程安全(二)

2012-11-05 
深入浅出GUI线程安全(二)?原文地址:?http://twaver.servasoft.com/?p562?继上一篇之后应该以后可以少解释

深入浅出GUI线程安全(二)

?

原文地址:?http://twaver.servasoft.com/?p=562

?

继上一篇之后应该以后可以少解释为什么要考虑线程安全的了,这篇的重点是如何保证GUI线程安全。

电信网管里最常见的场景莫过于后来来了个告警需要更新界面网元,很多TWaver客户得到后台来的告警信息后很自然的去调用DataBox里Element的AlarmState,或者通过Alarm对象驱动AlarmModel了,这时问题就来了,不管你用的JMS,COBOL,MQ或者是自己起的Socket连接给你的message的thread绝对不是EDT的线程中,所以如果你直接在得到消息后更新UIModel或者UI就是违背了GUI的线程安全原则。

这种情况下你唯一能做的就是将你要做的任务注册到EDT的事件派发队列里面,如果用Swing可以调用SwingUtilities.invokeAndWait或invokeLater,用SWT可以调用Display.asyncExec或syncExec,用Silverlight和WPF可以调用Dispatcher.BeginInvoke,这样通过注册Runnable或者Action之类的任务,等待着EDT在它有空处理你的时候就会调用你的注册的Runnable或Action执行动作了,这时候在里面就是这个唯一的UI Thread在运行了,这里面你大可放心的去操作UI或绑定UI的Model,唯一需要注意的是UI Thread全局就一个在工作,当你在执行时用户界面是不会得到任何响应的,因此你必须快速处理别站着茅坑***,假设你处理了半分钟,那对用户来说他会告诉你死机了半分钟。(有人留意到我怎么没提到Flex和JavaScript的调用函数,这两个UI平台比较特殊,下篇我再细讲)。

TWaver的Demo的有很多地方都有模拟实时更新的应用,大家可以参考一下
深入显出GUI线程安全(二)

以上代码已经说明了我想说的重点,也就是当你expand目录节点时TWaver才需要你动态加载子目录数据,expend时回调的loadChildren事件就是在EDT中,而读取磁盘文件是耗时的操作,如果你直接在EDT里面查询子目录并且创建对于的element信息,肯定界面需要堵塞住知道磁盘子目录和文件读完界面才有反应,TWaver Demo的实现起了个线程去做获取数据的工作,这里注意到element其实是在普通线程创建的,这里没有问题因为其还未添加到box,还不会影响到view上,而box已经和tree绑定了,因此对box的操作必然会影响tree的更新,因此数据获并且创建成element对象之后才通过SwingUtilities.invokeLater将element添加给box,这样你才有肯呢个看到右边不断滚动的tracing信息。

面包啃完了,浓茶被我冲泡得像白开水了,先睡了明天继续

?

热点排行