在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中,就是如下的代码:
- ProgressMonitorDialog progress = new ProgressMonitorDialog(null);
- progress.setCancelable(true);
- try {
- progress.run(true, true, new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
- throws InvocationTargetException {
- doSomething();
- }
- });
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
-
- }
第二行中的progress.setCancelable(true)是为了允许客户在长时间执行后台进程的时候,可以取消掉进程的执行。这里我把实际的执行过程Extract了出来,免得方法太长,doSomething()看起来应该是这样子的:
- public void doSomething(IProgressMonitor monitor) {
- monitor.beginTask("Beginning...", IProgressMonitor.UNKNOWN);
- monitor.subTask("Doing first job");
- doFirstThing();
- if(monitor.isCanceled()) return;
- monitor.worked(1);
- monitor.subTask("Doing second job");
- doSecondThing();
- if(monitor.isCanceled()) return;
- monitor.worked(2);
- ......
- monitor.done();
- }
- }
这样子当用户点击ProgressMonitor的Cancel按钮时,monitor.isCanceled()就会返回true,doSomething便中止执行。
说到这里,可能就会有疑问了,monitor.isCanceled()方法只会在doFirstThing()和doSecondThing()之间才会被触发,那么如果doFirstThing()的过程中有异常情况而导致无法返回,那点击Cancel就根本没有作用啊?
唔......这个就是问题的核心所在了,我不知道别人是如何解决的,在这里我只说一下我的解决方案,希望能够起到抛砖引玉的作用:
在前面已经提到,我使用了Job来处理异步线程,然而Job是通过调用job.schedule来执行的,用户无法确保job被执行的时机以及何时结束,一般的方法是使用Listener,Observer或者某个信号量来指示Job的结束。在有些地方我用的是Observer模式,而在这种情况下,我用的是boolean变量来做指示。于是,上面的doSomething就变成了:
- public void doSomething(IProgressMonitor monitor) {
- monitor.beginTask("Beginning...", IProgressMonitor.UNKNOWN);
- monitor.subTask("Doing first job");
- job.schedule();
- while (!jobFinished) {
- if (monitor.isCanceled()) {
- logger.info("monitor is canceled");
- job.cancel();
- return;
- }
- monitor.worked(times);
- times++;
- }
- monitor.done();
- }
- }
这样,只要while循环没有满足结束条件,我们就可以通过点击Cancel按钮来cancel掉Job。如果job中还有些东西是无法自动cancel掉的话,比如Socket通信等,我们还可以在job.cancel()前面加上一些代码来做这样的工作,比如job.getSocket().close()等,当然还要处理好各种Exception。
在Eclipse的Article里面,有几篇分别讲述Job和ProgressMonitor的文章,很是详细,有兴趣的朋友不妨找来看看。不过文章只是讲解原理性的东西,开发中所碰到的问题,还是要靠个人的经验来分析解决......所以,还是多多coding,多多thinking,提高解决实际问题的能力吧:)
分享到:
- 2007-01-17 17:13
- 浏览 6054
- 评论(7)
- 论坛回复 / 浏览 (7 / 10288)
- 查看更多
相关推荐
至于性能优化,你可能需要学习如何减少内存占用、提高启动速度,以及如何合理使用线程和异步编程。 最后,课程可能还会涵盖RCP的部署策略,包括如何创建可执行的RCP应用程序、发布更新以及如何使用产品配置文件...
在实际项目中,这些操作可能会更加复杂,涉及到更多细节和优化,如异步处理、多线程、UI更新同步等问题。如果要深入学习RCP开发,还需要掌握Eclipse插件开发、SWT/JFace UI组件、模型-视图-控制器(MVC)设计模式等...
5. **Command Framework**:命令框架是Eclipse RCP中处理用户操作的核心机制,它将动作和UI元素解耦,使代码更易于维护和扩展。 **四、实战技巧与最佳实践** 1. **插件设计原则**:尽量保持插件小巧且专注,避免...
在开发SWT应用程序时,尤其是在RCP(Rich Client Platform)环境中,多线程处理是常见的需求,以确保用户界面的响应性和程序的高效性。本文将深入探讨SWT中多线程的使用,特别是与UI交互相关的多线程原理。 首先,...
此外,为了提供良好的用户体验,可能会有线程管理的设计,比如使用SwingWorker或者ExecutorService来异步加载音乐文件和处理播放操作,避免阻塞UI主线程。 最后,考虑到软件的可扩展性和维护性,项目的代码结构应该...
开发Eclipse RCP应用时,开发者还需要关注性能优化,因为资源管理器需要处理大量文件和目录,可能需要使用缓存策略和异步加载机制以提高响应速度。同时,为了保证良好的用户体验,软件应具备多线程处理能力,允许...
3. 异步任务:为了执行耗时操作,通常会创建后台线程,完成后通过回调更新GUI。 三、布局管理 1. 布局(Layout):SWT提供多种布局管理器,如填充布局(FillLayout)、网格布局(GridLayout)、卡片布局...
8. **线程与异步编程**:由于GUI操作通常需要在事件循环中执行,教程会介绍如何正确处理线程,避免阻塞用户界面,以及利用Display和Job类进行异步任务处理。 9. **示例代码**:教程中应包含丰富的代码示例,帮助...
这个资源包包含了丰富的Java库,覆盖了从基础数据类型操作到复杂的网络通信、多线程处理、数据库操作、图形用户界面(GUI)设计等各个方面。以下是一些重要的Java类库及其相关知识点的详细解释: 1. **基础工具库**...
同时,理解如何使用JFace和RCP(Rich Client Platform)来构建更复杂的桌面应用也是必不可少的。 5. **网络编程**: 在Java中,`java.net`和`java.nio`包提供了网络通信所需的基本功能。学习TCP和UDP套接字的使用,...
10. **异步操作**:在Eclipse RCP环境中,通常推荐使用异步方式执行数据库查询,以避免阻塞UI线程。 通过理解并应用这些知识点,你可以创建一个功能完备的SWT SQLServer分页组件,为用户提供流畅的数据浏览体验。...
2. **异步编程**:JavaScript是单线程的,但通过事件循环和回调函数、Promise以及async/await,开发者可以处理复杂的异步操作,提升应用性能。 3. **前端框架与库**:书中可能会涉及Angular、React或Vue.js等主流...
- **异步调用**:客户端可以选择异步方式等待结果,避免阻塞当前线程。 - **心跳机制**:保持连接活跃,减少因网络问题导致的重连次数。 ### 应用场景 Hadoop RPC广泛应用于Hadoop生态系统中的各种组件,如HDFS的...
- **性能优化技巧**:包括减少HTTP请求、压缩资源、异步处理等方法。 - **错误处理与日志记录**:理解和实施有效的错误处理策略,以及使用日志记录工具进行问题排查。 通过这个Eclipse RAP教程,你可以逐步掌握...
3. **Servlet容器实现**:源码揭示了Jetty作为Servlet容器的内部实现,包括请求和响应处理、Servlet的加载和管理、线程模型以及会话管理等核心功能。这有助于深入理解Servlet容器的工作机制。 4. **WebSocket支持**...
C#的多线程和异步处理能力可以帮助ReCapProject API更高效地运行。通过合理设计并发策略,可以显著提升数据处理速度,尤其是在处理大型项目时。 七、应用程序集成与部署 最后,我们需要将开发的功能整合成一个完整...
开发者需要掌握如何使用MediaPlayer加载、播放、控制视频流,并处理播放过程中的错误。同时,考虑到用户界面,可能需要使用SurfaceView或TextureView来显示视频画面,并结合MediaController实现播放控制条。 此外,...