<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 20, comments - 16, trackbacks - 0, articles - 0

    (轉載)RCP中異步線程的處理

    Posted on 2008-07-01 18:08 Raul Gong 閱讀(700) 評論(0)  編輯  收藏 所屬分類: eclipse

    轉載自:http://www.javaeye.com/topic/47919   感謝原作者

    在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(truetruenew 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就根本沒有作用?。?br />
    唔......這個就是問題的核心所在了,我不知道別人是如何解決的,在這里我只說一下我的解決方案,希望能夠起到拋磚引玉的作用:

    在前面已經提到,我使用了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.     }   


    這樣,只要while循環沒有滿足結束條件,我們就可以通過點擊Cancel按鈕來cancel掉Job。如果job中還有些東西是無法自動cancel掉的話,比如Socket通信等,我們還可以在job.cancel()前面加上一些代碼來做這樣的工作,比如job.getSocket().close()等,當然還要處理好各種Exception。

    在Eclipse的Article里面,有幾篇分別講述Job和ProgressMonitor的文章,很是詳細,有興趣的朋友不妨找來看看。不過文章只是講解原理性的東西,開發中所碰到的問題,還是要靠個人的經驗來分析解決......所以,還是多多coding,多多thinking,提高解決實際問題的能力吧:)


    ProgressMonitor的Article:

    http://www.eclipse.org/articles/Article-Progress-Monitors/article.html
    主站蜘蛛池模板: 中文字幕在线观看免费视频| 免费观看一区二区三区| 中文字幕无码播放免费| 亚洲国产综合专区电影在线| 你好老叔电影观看免费| 国产亚洲av片在线观看18女人| 特级做a爰片毛片免费看| 免费不卡中文字幕在线| 成人一级免费视频| 亚洲精品无码久久久久AV麻豆| 成人久久久观看免费毛片| 亚洲男人的天堂一区二区| eeuss影院www天堂免费| 亚洲色精品aⅴ一区区三区| 精品一卡2卡三卡4卡免费视频| 国产精品亚洲午夜一区二区三区| 日韩午夜理论免费TV影院 | 日韩免费一区二区三区| 国产成人久久精品亚洲小说| 亚洲av高清在线观看一区二区| www一区二区www免费| 在线亚洲97se亚洲综合在线 | 亚洲精品无码中文久久字幕| 国产一区二区三区无码免费| 亚洲精品视频免费观看| 久久精品国产亚洲AV麻豆不卡| 精品国产污污免费网站aⅴ | 波多野结衣免费在线| 亚洲欧美日韩中文高清www777| 一本色道久久88亚洲综合| 在线看片免费人成视频久网下载| 亚洲综合自拍成人| 在线免费视频一区二区| 国产免费一区二区三区免费视频| 亚洲资源在线视频| 国产一区视频在线免费观看| 日本免费电影一区二区| 国产精品亚洲一区二区在线观看| 亚洲午夜国产精品无码老牛影视| 色影音免费色资源| 一级做a爰性色毛片免费|