Eclipse RCP的:停止线程/工作,冻结 [英] Eclipse RCP: Stopping a thread/job that freezes

查看:213
本文介绍了Eclipse RCP的:停止线程/工作,冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法:

TraceData.getTraceData(true);

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

This trace method takes very long or freezes if the external interface is not configured properly. So it does not even return a null. It just hangs.

在这种情况下,我想实现一个弹出的窗口中有一个按钮取消以停止此方法。

In this case I want to implement a pop up dialog box with a button "Cancel" to stop this method.

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

So I created a Job to run this method:

    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;
      }
    };

然后,我创建了一个单选项停止跟踪的对话框。

Then I created a dialog box with a single option to stop the trace.

 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();

时,如果跟踪完成该对话框会自动消失。因此,主线程应该停止在此对话框中,等待迹可完成。或者,如果用户点击取消,将停​​止跟踪。

This dialog box should automatically disappear when the if tracing is done. So the main thread should stop at this dialog box and wait for the trace to be finished. Or if the user clicks cancel it will stop the trace.

修改

感谢亚历山大我想出了以下,但它仍然有几个问题。我需要把假在dialog.run()叉,否则我一个GET SWT像<一个线程访问错误href="http://stackoverflow.com/questions/23779548/cancel-button-in-progressmonitordialog-and-invocationtargetexception">this.此外,我在使用之前才​​来更新我的UI的Display.getDefault()。asyncExec(),但在这里它没有被激活。最后取消按钮不工作,也就是说,它不能是pressed。但是,进度条的工作。

Thanks to Alexander I came up with following, but it still has a couple of issues. I needed to put false for the fork in dialog.run(), otherwise I a get SWT thread access error like this. Also I used the Display.getDefault().asyncExec() before to update the my UI before, but here it is not being activated. Lastly the cancel button is not working, i.e. it cannot be pressed. But the progress bar is working.

        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();
        }

推荐答案

有什么可以用的是ProgressMonitorDialog:它有可能取消的工作,并显示您的进展

What you could use is ProgressMonitorDialog: it has possibility to cancel the work and show your progress.

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(真); 的实施。也许你不会使用,而循环,而是检查不时如果取消对话框。

This example would probably needs to be adjusted for your requirements and TraceData.getTraceData(true); implementation. Probably you wouldn't use while cycle but rather checking time to time if dialog is cancelled.

我认为你必须有主要的问题是,你把线程睡眠的部分。既然你正在执行其在UI线程,你实际上是把UI线程睡眠。这就是为什么既没有取消按钮,也没有其他的部分,要更新 asynchExec 你的用户界面的工作。

I think that the main problem you have there is the part where you put Thread to sleep. Since you are executing it in the UI thread, you are actually putting the UI Thread to sleep. That is why neither cancel button, nor other part, where you want to update your UI in asynchExec is working.

我建议你创建一个<一个href="http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2Fjobs%2Fpackage-use.html"相对=nofollow>工作。这将创建一个非UI线程,它可以用于检查,如果显示器被取消或更新某些状态变量或什么的。

I'd suggest you to create a Job. This will create another non-UI Thread, which can be used for checking, if monitor is cancelled or updating some state variables or whatever.

这篇关于Eclipse RCP的:停止线程/工作,冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆