国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

關于Eclipse中UI程序的線程的討論

2024-07-21 02:14:54
字體:
來源:轉載
供稿:網友
  雖然各個操作系統之間的線程機制是不一樣的,但是大致是相同的。當用戶使用gui程序時,如果點鼠標或按下鍵盤上的鍵等時,操作系統會產生對應的gui事件,它來決定哪個窗口或程序來接受每一個事件并且放到程序的事件隊列中.

      任何gui程序的底層結構就是一個事件循環.程序首先初始化事件循環,并開始循環,這個循環會從事件隊列依次接收gui事件并一一做出相應的反應.程序應該對事件做出快速的反應使程序一直對用戶有響應,舉個例子,用戶點了一下程序里的一個按鈕結果程序就沒反應了,那么這個程序應該算是一個失敗的程序吧.

      如果某個ui事件引發了某個需要長時間的事務,那么應該把它放到一個另外的單獨的線程中,這樣程序的那個事件循環就能夠馬上回來響應用戶的下一個操作.線程是非常復雜的一個主題,如果處理的不好很容易造成死鎖等很糟糕的情況.

      還好,eclipse為我們開發插件提供了一個方便的ui線程包,大大的簡化了很多底層復雜的東西.先看看幾個簡單的概念.

  1.swt ui線程

  swt用的是操作系統直接支持的線程模式,程序會在主程序里運行一個時間循環并依次在這個線程里響應事件.看下面這段代碼,ui線程就是創建display的那個線程.

public static void main (string [] args) {
      display display = new display ();
      shell shell = new shell (display);
      shell.open ();
      // 開始事件循環
      // 關掉窗口后
      while (!shell.isdisposed ()) {
         if (!display.readanddispatch ())
            display.sleep ();
      }
      display.dispose ();
   }

  簡單的小程序里,一個ui線程就能夠滿足需要了。但如果是長時間的操作,你就最好不要用ui線程來做這些事,可以交給job去做.它其實就是另外啟動的線程,也就是等會我要說的非ui線程.

  2、job

  job類由org.eclipse.core.runtime插件提供.它能夠讓客戶程序員輕松的在另外的線程中執行代碼。看一個小例子:

  job job = new job("my first job") {
     protected istatus run(iprogressmonitor monitor) {
           system.out.println("hello world (from a background job)");
           return status.ok_status;
        }
     };
  job.setpriority(job.short);
  job.schedule(); // start as soon as possible

  job的默認優先級是job.long,這里例子中的優先級要比它高,只要調用job#schedule(),它就會盡快在另外的線程中運行run()中的代碼。再看一個小例子:

final job job = new job("long running job") {
        protected istatus run(iprogressmonitor monitor) {
           try {
              while(hasmoreworktodo()) {
                 // do some work
                 // ...
              if (monitor.iscanceled()) return status.cancel_status;
             }
              return status.ok_status;
           } finally {
              schedule(60000); // start again in an hour
           }
        }
     };
  job.addjobchangelistener(new jobchangeadapter() {
        public void done(ijobchangeevent event) {
        if (event.getresult().isok())
           postmessage("job completed successfully");
           else
              posterror("job did not complete successfully");
        }
     });
  job.setsystem(true);
     job.schedule(); // start as soon as possible

  monitor是一個進度顯示條,它會在運行job時自動顯示,如果任務成功運行完成,返回status.ok_status,如果中途被用戶在進度顯示條那里中斷,就返回status.cancel_status.上面schedule(60000);它是讓job每過1小時就自動運行,job又一個非常強大的功能。然后后面是可以給job添加監聽器,
job.setsystem(true);這一句是把這個job設置為系統級別的.如果調用setuser(true),那么就被定義為用戶級別的,用戶級別和默認級別的job。

  在運行時會以ui形式反映出來,如果是用戶job,那么會彈出一個進度顯示窗口,能讓用戶選擇在后臺里運行,下圖是一個job自動運行時的效果:


 
  再介紹job常常用到的一個方法job#join(),系統調用到某個job,調用它的run()方法。再看下面這個例子:

    class trivialjob extends job {
      public trivialjob() {
         super("trivial job");
      }
      public istatus run(iprogressmonitor monitor) {
         system.out.println("this is a job");
         return status.ok_status;
      }
   }
  
  job的創建和計劃如下所示:

   trivialjob job = new trivialjob();
   system.out.println("about to schedule a job");
   job.schedule();
   system.out.println("finished scheduling a job");
  
  他們的執行是和時間沒關系的,輸出可能如下:

   about to schedule a job
   this is a job
   finished scheduling a job

  也可能是:

   about to schedule a job
   finished scheduling a job
   this is a job
   
  如果希望某個job運行完成后在繼續時,可以使用join()方法,join()會一直阻塞到該job運行完。
  
  例子:

   trivialjob job = new trivialjob();
   system.out.println("about to schedule a job");
   job.schedule();
   job.join();
   if (job.getresult().isok())
      system.out.println("job completed with success");
   else
      system.out.println("job did not complete successfully");

  上面的代碼執行后,輸出應該就是這樣:

 about to schedule a job
   this is a job
   job completed with success

  job的功能是很強大的,還有很多功能我以后會介紹,也可以查閱官方幫助文檔,這里先把幾個常用的問題解決掉。參見:

http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/runtime_jobs.htm

  3、如果在job中加上改變ui的代碼就會失敗。原因如下:

  如果是在非ui線程中調用ui,swt就會拋出一個swtexception,要在一個非ui線程改變ui的話有幾種技術:

  第一種,用:

display#syncexec(runnable)或
diaplay#asyncexec(runnable)

  第二種:

  已經開發了另外一種job,就是uijob,可以直接在它里面運行改變ui的代碼,其實它就是在swt的asyncexec()方法里運行的.所有繼承uijob的類應該覆寫runinuithread方法而不是run方法。

  3.關于進度顯示

  在jface中:

  org.eclipse.jface.operations包定義了一些接口用來在進度條下運行長時間的任務。可以參見:
http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/jface_operations.htm

  在eclipse插件和rcp開發中:

  用戶級別的job是互操作性最強的,它不僅能夠讓用戶用cancel鍵取消job,而且可以在detail中展示具體情況,但是注意:

  detail只會在下面兩種方法中出現:

  iprogressservice#busycursorwhile或
  iprogressservice#runinui

  1)iprogressservice#busycursorwhile的用法例子:

  注意這里的run()中做些和ui無關的事:

iprogressservice progressservice = platformui.getworkbench().getprogressservice();
   progressservice.busycursorwhile(new irunnablewithprogress(){
      public void run(iprogressmonitor monitor) {
         //do non-ui work
      }
   });

  效果:



  2) iprogressservice#runinui的用法例子:

  注意這里的run()中可以做些和ui有關的事。

progressservice.runinui(
      platformui.getworkbench().getprogressservice(),
      new irunnablewithprogress() {
         public void run(iprogressmonitor monitor) {
            //do ui work
         }
      },
      platform.getworkspace().getroot());

  效果:



  這里最后一個參數可以是null,或者是這個操作的規則,在這里我們是設定運行這個ui操作時鎖定工作臺.

  更加具體的可以參見:

http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_jobs.htm

  另外,有少數時候,我們不想彈出一個進度條窗口,而是只在最底下的狀態欄顯示就可以了,很簡單,寫自己的job類時,在構造方法里加上一句:setuser(false);就可以了.



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建湖县| 佛山市| 遵义市| 江城| 彰化市| 扎赉特旗| 新源县| 大洼县| 财经| 陕西省| 自贡市| 新竹市| 增城市| 汝南县| 永济市| 新和县| 抚松县| 平果县| 宁陵县| 鲁甸县| 临西县| 凤翔县| 崇礼县| 宁蒗| 临洮县| 中卫市| 东明县| 屏山县| 上思县| 肇庆市| 桑日县| 三台县| 百色市| 沙湾县| 松原市| 始兴县| 杂多县| 安泽县| 陆川县| 门头沟区| 梅州市|