`
sonic126
  • 浏览: 20755 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

RCP中异步线程的处理 (转)

    博客分类:
  • RCP
阅读更多
在RCP中要在非UI线程中执行UI线程的操作,最简单的方式就是display.syncExec或者display.asyncExec,如果UI线程所需的时间较长的话,则应该使用display.asyncExec

在执行异步线程的时候,我们一般应当继承Job或者UIJob类:UIJob是在UI线程中运行的,可以直接访问窗体组件。Job是在非UI线程中运行,如果在里面想访问窗体组件,需要通过Display.asynExec()或者synExec方式来执行。UIJob要尽量的短,不要过多的占用UI线程的时间。

在我现在的系统中,每当UI需要和Server交互的时候,都需要检测Server是否启动,如果未启动的话,尝试启动三次,三次不成功则抛出Exception,用 MessageDialog给用户提示,启动成功以后,还需载入相关信息。这样的异步线程,就只能放到Job中执行。

然而,这样还是远远不够的,试想一下,如果点完一个MenuItem以后,过了很久才会有所反应,这种用户体验岂不是糟糕透了?于是我们还要提供进度条来提高用户体验度,在RCP中,就是如下的代码:

   1. ProgressMonitorDialog progress = new ProgressMonitorDialog(null); 
   2. progress.setCancelable(true); 
   3. try { 
   4.       progress.run(true, true, new IRunnableWithProgress() { 
   5.         public void run(IProgressMonitor monitor) 
   6.                 throws InvocationTargetException { 
   7.               doSomething(); 
   8.           } 
   9.       }); 
  10. } catch (InvocationTargetException e) { 
  11.       e.printStackTrace(); 
  12. } catch (InterruptedException e) { 
  13.  
  14. } 



第二行中的progress.setCancelable(true)是为了允许客户在长时间执行后台进程的时候,可以取消掉进程的执行。这里我把实际的执行过程Extract了出来,免得方法太长,doSomething()看起来应该是这样子的:

   1. public void doSomething(IProgressMonitor monitor) { 
   2.           monitor.beginTask("Beginning...", IProgressMonitor.UNKNOWN);
   3.          monitor.subTask("Doing first job");
   4.          doFirstThing();
   5.          if(monitor.isCanceled()) return;
   6.           monitor.worked(1);
   7.          monitor.subTask("Doing second job");
   8.          doSecondThing();
   9.          if(monitor.isCanceled()) return;
  10.          monitor.worked(2);
  11.          ......
  12.           monitor.done(); 
  13.       }  
  14. } 



这样子当用户点击ProgressMonitor的Cancel按钮时,monitor.isCanceled()就会返回 true,doSomething便中止执行。

说到这里,可能就会有疑问了,monitor.isCanceled()方法只会在doFirstThing()和doSecondThing()之间才会被触发,那么如果doFirstThing()的过程中有异常情况而导致无法返回,那点击Cancel就根本没有作用啊?

唔......这个就是问题的核心所在了,我不知道别人是如何解决的,在这里我只说一下我的解决方案,希望能够起到抛砖引玉的作用:

在前面已经提到,我使用了Job来处理异步线程,然而Job是通过调用job.schedule来执行的,用户无法确保job被执行的时机以及何时结束,一般的方法是使用Listener,Observer或者某个信号量来指示Job的结束。在有些地方我用的是Observer模式,而在这种情况下,我用的是boolean变量来做指示。于是,上面的doSomething就变成了:

   1. public void doSomething(IProgressMonitor monitor) { 
   2.           monitor.beginTask("Beginning...", IProgressMonitor.UNKNOWN);
   3.          monitor.subTask("Doing first job");
   4.          job.schedule();
   5.          while (!jobFinished) {
   6.             if (monitor.isCanceled()) {
   7.              logger.info("monitor is canceled");
   8.              job.cancel();
   9.              return;
  10.             }
  11.             monitor.worked(times);
  12.             times++;
  13.          }
  14.          monitor.done(); 
  15.       }  
  16. }


这样,只要while循环没有满足结束条件,我们就可以通过点击Cancel按钮来cancel掉Job。如果job中还有些东西是无法自动cancel 掉的话,比如Socket通信等,我们还可以在job.cancel()前面加上一些代码来做这样的工作,比如 job.getSocket().close()等,当然还要处理好各种Exception。

在Eclipse的Article里面,有几篇分别讲述Job和ProgressMonitor的文章,很是详细,有兴趣的朋友不妨找来看看。不过文章只是讲解原理性的东西,开发中所碰到的问题,还是要靠个人的经验来分析解决......所以,还是多多coding,多多thinking,提高解决实际问题的能力吧:)

转自JavaEye社区http://www.iteye.com/post/275070
分享到:
评论

相关推荐

    RCP部分课程

    至于性能优化,你可能需要学习如何减少内存占用、提高启动速度,以及如何合理使用线程和异步编程。 最后,课程可能还会涵盖RCP的部署策略,包括如何创建可执行的RCP应用程序、发布更新以及如何使用产品配置文件...

    rcp收集资料上传

    在实际项目中,这些操作可能会更加复杂,涉及到更多细节和优化,如异步处理、多线程、UI更新同步等问题。如果要深入学习RCP开发,还需要掌握Eclipse插件开发、SWT/JFace UI组件、模型-视图-控制器(MVC)设计模式等...

    eclipse-rcp开发培训PPT

    5. **Command Framework**:命令框架是Eclipse RCP中处理用户操作的核心机制,它将动作和UI元素解耦,使代码更易于维护和扩展。 **四、实战技巧与最佳实践** 1. **插件设计原则**:尽量保持插件小巧且专注,避免...

    swt 多线程

    在开发SWT应用程序时,尤其是在RCP(Rich Client Platform)环境中,多线程处理是常见的需求,以确保用户界面的响应性和程序的高效性。本文将深入探讨SWT中多线程的使用,特别是与UI交互相关的多线程原理。 首先,...

    mp3 manger code

    此外,为了提供良好的用户体验,可能会有线程管理的设计,比如使用SwingWorker或者ExecutorService来异步加载音乐文件和处理播放操作,避免阻塞UI主线程。 最后,考虑到软件的可扩展性和维护性,项目的代码结构应该...

    file explorer

    开发Eclipse RCP应用时,开发者还需要关注性能优化,因为资源管理器需要处理大量文件和目录,可能需要使用缓存策略和异步加载机制以提高响应速度。同时,为了保证良好的用户体验,软件应具备多线程处理能力,允许...

    SWT综合教程及安装指导

    3. 异步任务:为了执行耗时操作,通常会创建后台线程,完成后通过回调更新GUI。 三、布局管理 1. 布局(Layout):SWT提供多种布局管理器,如填充布局(FillLayout)、网格布局(GridLayout)、卡片布局...

    Java类库大全

    这个资源包包含了丰富的Java库,覆盖了从基础数据类型操作到复杂的网络通信、多线程处理、数据库操作、图形用户界面(GUI)设计等各个方面。以下是一些重要的Java类库及其相关知识点的详细解释: 1. **基础工具库**...

    J2SE进阶,java深入开发

    同时,理解如何使用JFace和RCP(Rich Client Platform)来构建更复杂的桌面应用也是必不可少的。 5. **网络编程**: 在Java中,`java.net`和`java.nio`包提供了网络通信所需的基本功能。学习TCP和UDP套接字的使用,...

    Java程序设计之swt教程.rar

    8. **线程与异步编程**:由于GUI操作通常需要在事件循环中执行,教程会介绍如何正确处理线程,避免阻塞用户界面,以及利用Display和Job类进行异步任务处理。 9. **示例代码**:教程中应包含丰富的代码示例,帮助...

    swt sqlserver分页组件

    10. **异步操作**:在Eclipse RCP环境中,通常推荐使用异步方式执行数据库查询,以避免阻塞UI线程。 通过理解并应用这些知识点,你可以创建一个功能完备的SWT SQLServer分页组件,为用户提供流畅的数据浏览体验。...

    JavaScript富应用开发

    2. **异步编程**:JavaScript是单线程的,但通过事件循环和回调函数、Promise以及async/await,开发者可以处理复杂的异步操作,提升应用性能。 3. **前端框架与库**:书中可能会涉及Angular、React或Vue.js等主流...

    hadoop rpc实例

    - **异步调用**:客户端可以选择异步方式等待结果,避免阻塞当前线程。 - **心跳机制**:保持连接活跃,减少因网络问题导致的重连次数。 ### 应用场景 Hadoop RPC广泛应用于Hadoop生态系统中的各种组件,如HDFS的...

    eclipse rap教程

    - **性能优化技巧**:包括减少HTTP请求、压缩资源、异步处理等方法。 - **错误处理与日志记录**:理解和实施有效的错误处理策略,以及使用日志记录工具进行问题排查。 通过这个Eclipse RAP教程,你可以逐步掌握...

    ReCapProject

    C#的多线程和异步处理能力可以帮助ReCapProject API更高效地运行。通过合理设计并发策略,可以显著提升数据处理速度,尤其是在处理大型项目时。 七、应用程序集成与部署 最后,我们需要将开发的功能整合成一个完整...

    eclipse-jetty-plugin-master_源码.rar

    3. **Servlet容器实现**:源码揭示了Jetty作为Servlet容器的内部实现,包括请求和响应处理、Servlet的加载和管理、线程模型以及会话管理等核心功能。这有助于深入理解Servlet容器的工作机制。 4. **WebSocket支持**...

    基于android平台的视频播放器设计说明.doc

    开发者需要掌握如何使用MediaPlayer加载、播放、控制视频流,并处理播放过程中的错误。同时,考虑到用户界面,可能需要使用SurfaceView或TextureView来显示视频画面,并结合MediaController实现播放控制条。 此外,...

Global site tag (gtag.js) - Google Analytics