2014-11-05 55 views
0

我有一個方法:Eclipse RCP的:停止線程/作業凍結

TraceData.getTraceData(true); 

此跟蹤方法需要很長或者外部接口配置不正確凍結。所以它甚至不會返回null。它只是掛起。

在這種情況下,我想實現一個彈出式對話框,並帶有「取消」按鈕來停止此方法。

所以我創建了一個作業來運行這個方法:

final Job job = new Job("Trace Job") { 
     @Override 
     protected IStatus run(IProgressMonitor monitor) { 


      TraceData.getTraceData(true); 


      Display.getDefault().asyncExec(new Runnable() { 
      @Override 
      public void run() { 
       MessageDialog.openInformation(shell, "Your Popup ","Your job has finished."); 
      } 
     }); 
     return Status.OK_STATUS; 
     } 
    }; 

然後,我創建了一個對話框,其中一個選項,以停止跟蹤。

Shell shell2 = new Shell(); 
final MessageBox dialog = new MessageBox(shell2, SWT.ICON_QUESTION | SWT.CANCEL); 

dialog.setText("Tracing"); 
dialog.setMessage("Cancel Tracing ?"); 

int cancelTrace = dialog.open(); 

如果跟蹤完成,該對話框應該會自動消失。所以主線程應該停在這個對話框並等待跟蹤完成。或者如果用戶點擊取消,它將停止跟蹤。

編輯

感謝亞歷山大我想出了下面的,但它仍然有幾個問題。我需要在dialog.run()中爲叉設置false,否則我會得到SWT線程訪問錯誤,如this。此外,我之前使用Display.getDefault()。asyncExec()更新了我的用戶界面,但在此處未激活。最後取消按鈕不起作用,即它不能被按下。但進度條正在工作。

 ProgressMonitorDialog dialog = new ProgressMonitorDialog(Display.getDefault().getActiveShell()); 
     try { 
      dialog.run(false, true, new IRunnableWithProgress() { 

       @Override 
       public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { 

        monitor.beginTask("Tracing", 10); 

        for(int i = 0; i < 10; i++){ 

         // Check if the user pressed "cancel" or method has finished 
         if(monitor.isCanceled() || finished == true){ 
          System.out.println("Cancel Pressed or Finished"); 
          monitor.done(); 
          return; 
         }else{ 
          Display.getDefault().readAndDispatch(); 
         } 

         if (i == 0){ // run only once 
          System.out.println("Here"); 
          Display.getDefault().asyncExec(new Runnable() { 
           @Override 
           public void run() { 
           try { 
            System.out.println("Start Trace"); 
            Thread.sleep(4000); // represents long method 

            finished = true; 
           } catch (InterruptedException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
           } 
           } 
          }); 
         } 

         // Optionally add subtasks 
         monitor.subTask("Time passed: " + (i * 500) + " ms"); 

         Thread.sleep(500); 

         // Tell the monitor that you successfully finished one item of "workload"-many 
         monitor.worked(1); 

        } 
        // You are done 
        monitor.done(); 
       } 
      }); 
     } catch (InvocationTargetException | InterruptedException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

enter image description here

+0

你忘了問一個問題。你講了一個故事,然後停下來不問問題。 – 2014-11-05 12:03:38

回答

2

什麼,你可以用的是ProgressMonitorDialog:它有可能取消工作,並顯示你的進步。

ProgressMonitorDialog dialog = new ProgressMonitorDialog(Display.getDefault().getActiveShell()); 
     try { 
      dialog.run(true, true, new IRunnableWithProgress() { 

       @Override 
       public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { 
        monitor.beginTask("Tracing", 100); 
        while(!monitor.isCanceled()) { 
         Display.getDefault().readAndDispatch(); 
         // Do your work here 
        } 
       } 
      }); 
     } catch (InvocationTargetException | InterruptedException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

此示例可能需要根據您的要求和TraceData.getTraceData(true);實施進行調整。可能你不會使用while循環,而是在對話被取消時不時檢查。

我認爲你存在的主要問題是你放置線程進入睡眠狀態的部分。由於您正在UI線程中執行它,因此實際上將UI線程置於睡眠狀態。這就是爲什麼在asynchExec中您想要更新UI的按鈕或其他部件都無法使用。

我建議你創建一個Job。這將創建另一個非UI線程,可用於檢查,如果監視器被取消或更新某些狀態變量或其他。

+0

謝謝。我仍然有幾個問題。如果你有時間可以看看嗎? – 2c00L 2014-11-09 00:46:58

+1

@ 2c00L請查看更新的答案。 – 2014-11-09 10:05:35

+0

好的。我設法解決了我的問題。我將所有內容放在syncExec()中,並使用一個作業調用我的long函數。然後等待作業完成或按取消停止凍結的方法。 – 2c00L 2014-11-10 15:16:53