Eclipse RCP的:停止线程/作业冻结(Eclipse RCP: Stopping a thr

2019-11-03 10:29发布

我有一个方法:

TraceData.getTraceData(true);

此跟踪方法需要很长的,或者如果外部接口配置不正确冻结。 因此,它甚至不返回空。 它只是挂起。

在这种情况下,我想实现一个按钮“取消”弹出对话框,停止该方法。

所以,我创建了一个作业运行此方法:

    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()叉,否则我一个GET SWT线程访问错误,像这样 。 此外,我用之前更新我的UI前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();
        }

Answer 1:

你可以使用是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线程睡觉。 这就是为什么既没有取消按钮,也没有其他的部分,要更新的UI asynchExec工作。

我建议你创建一个作业 。 这将创建一个非UI线程,它可以用于检查,如果监视器被取消或更新一些状态变量或什么的。



文章来源: Eclipse RCP: Stopping a thread/job that freezes