浏览 10286 次
锁定老帖子 主题:RCP中异步线程的处理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-16
在执行异步线程的时候,我们一般应当继承Job或者UIJob类:UIJob是在UI线程中运行的,可以直接访问窗体组件。Job是在非UI线程中运行,如果在里面想访问窗体组件,需要通过Display.asynExec()或者synExec方式来执行。UIJob要尽量的短,不要过多的占用UI线程的时间。 在我现在的系统中,每当UI需要和Server交互的时候,都需要检测Server是否启动,如果未启动的话,尝试启动三次,三次不成功则抛出Exception,用MessageDialog给用户提示,启动成功以后,还需载入相关信息。这样的异步线程,就只能放到Job中执行。 然而,这样还是远远不够的,试想一下,如果点完一个MenuItem以后,过了很久才会有所反应,这种用户体验岂不是糟糕透了?于是我们还要提供进度条来提高用户体验度,在RCP中,就是如下的代码:
第二行中的progress.setCancelable(true)是为了允许客户在长时间执行后台进程的时候,可以取消掉进程的执行。这里我把实际的执行过程Extract了出来,免得方法太长,doSomething()看起来应该是这样子的:
这样子当用户点击ProgressMonitor的Cancel按钮时,monitor.isCanceled()就会返回true,doSomething便中止执行。 说到这里,可能就会有疑问了,monitor.isCanceled()方法只会在doFirstThing()和doSecondThing()之间才会被触发,那么如果doFirstThing()的过程中有异常情况而导致无法返回,那点击Cancel就根本没有作用啊? 唔......这个就是问题的核心所在了,我不知道别人是如何解决的,在这里我只说一下我的解决方案,希望能够起到抛砖引玉的作用: 在前面已经提到,我使用了Job来处理异步线程,然而Job是通过调用job.schedule来执行的,用户无法确保job被执行的时机以及何时结束,一般的方法是使用Listener,Observer或者某个信号量来指示Job的结束。在有些地方我用的是Observer模式,而在这种情况下,我用的是boolean变量来做指示。于是,上面的doSomething就变成了:
这样,只要while循环没有满足结束条件,我们就可以通过点击Cancel按钮来cancel掉Job。如果job中还有些东西是无法自动cancel掉的话,比如Socket通信等,我们还可以在job.cancel()前面加上一些代码来做这样的工作,比如job.getSocket().close()等,当然还要处理好各种Exception。 在Eclipse的Article里面,有几篇分别讲述Job和ProgressMonitor的文章,很是详细,有兴趣的朋友不妨找来看看。不过文章只是讲解原理性的东西,开发中所碰到的问题,还是要靠个人的经验来分析解决......所以,还是多多coding,多多thinking,提高解决实际问题的能力吧:) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-17
ProgressMonitor的Article:
http://www.eclipse.org/articles/Article-Progress-Monitors/article.html |
|
返回顶楼 | |
发表时间:2007-01-24
引用 在RCP中要在非UI线程中执行UI线程的操作
没看明白。 RCP里面的异步执行display.asyncExec,实际上还是在UI线程中执行,只是采用了队列的形式来调度。 非UI线程是不允许修改界面元素的。我想这可能是基于同步考虑的简单实现。 |
|
返回顶楼 | |
发表时间:2007-01-25
在非UI的线程里面,如果想改变UI的组件,那么就要通过获得display,然后调用display.asyncExec()来处理
|
|
返回顶楼 | |
发表时间:2007-02-11
doFirstThing()方法只要抛出异常不就可以实现异常向上传递了 难道这样不行?
|
|
返回顶楼 | |
发表时间:2007-02-13
doFirstThing的执行过程,是无法被monitor.cancel终止的
|
|
返回顶楼 | |
发表时间:2007-04-28
设置为IProgressMonitor.UNKNOWN时
进度条只显示出来,并不前进 看了JFace代码好像JFace把IProgressMonitor.UNKNOWN的情况抛弃了 有遇到类似问题的么 |
|
返回顶楼 | |
发表时间:2007-04-29
嗯,你调用monitor.work(int n),就能前进了
|
|
返回顶楼 | |