Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Eclipse RCP:停止冻结的线程/作业_Java_Multithreading_Algorithm_User Interface_Eclipse Rcp - Fatal编程技术网

Java Eclipse RCP:停止冻结的线程/作业

Java Eclipse RCP:停止冻结的线程/作业,java,multithreading,algorithm,user-interface,eclipse-rcp,Java,Multithreading,Algorithm,User Interface,Eclipse Rcp,我有一个方法: TraceData.getTraceData(true); 如果外部接口配置不正确,此跟踪方法将花费很长时间或冻结。所以它甚至不返回null。它只是挂着 在这种情况下,我想实现一个弹出对话框,其中有一个按钮“Cancel”来停止这个方法 因此,我创建了一个作业来运行此方法: final Job job = new Job("Trace Job") { @Override protected IStatus run(IProgressMonitor

我有一个方法:

TraceData.getTraceData(true);
如果外部接口配置不正确,此跟踪方法将花费很长时间或冻结。所以它甚至不返回null。它只是挂着

在这种情况下,我想实现一个弹出对话框,其中有一个按钮“Cancel”来停止这个方法

因此,我创建了一个作业来运行此方法:

    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();
完成if跟踪后,此对话框应自动消失。因此,主线程应该停止在这个对话框中,等待跟踪完成。或者,如果用户单击“取消”,它将停止跟踪

编辑

多亏了Alexander,我提出了以下建议,但仍有一些问题。我需要在dialog.run()中为fork设置false,否则会出现SWT线程访问错误,如。我还使用了Display.getDefault().asyncExec()来更新之前的MyUI,但在这里它没有被激活。最后,取消按钮不工作,即无法按下。但进度条正在发挥作用

        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=newprogressMonitorDialog(Display.getDefault().getActiveShell());
试一试{
run(false、true、new-IRunnableWithProgress(){
@凌驾
public void run(IProgressMonitor监视器)抛出InvocationTargetException、InterruptedException{
monitor.beginTask(“跟踪”,10);
对于(int i=0;i<10;i++){
//检查用户是否按下“取消”或方法是否已完成
if(monitor.isCanceled()| | finished==true){
系统输出打印项次(“取消按下或完成”);
monitor.done();
返回;
}否则{
Display.getDefault().readAndDispatch();
}
如果(i==0){//只运行一次
System.out.println(“此处”);
Display.getDefault().asyncExec(新的Runnable()){
@凌驾
公开募捐{
试一试{
System.out.println(“开始跟踪”);
sleep(4000);//表示长方法
完成=正确;
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
});
}
//可以选择添加子任务
monitor.subTask(“经过的时间:”+(i*500)+“ms”);
睡眠(500);
//告诉班长您成功地完成了一项“工作负载”——多项
监测工作(1);
}
//你完了
monitor.done();
}
});
}捕获(InvocationTargetException | InterruptedException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}

您可以使用的是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)实现。您可能不会在循环时使用
,而是在对话框取消时不时检查

我认为你的主要问题是你把线放在睡觉的地方。因为您是在UI线程中执行它,所以实际上是将UI线程置于睡眠状态。这就是为什么在
asynchExec
中要更新UI的“取消”按钮和其他部分都不起作用的原因

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

我建议你创建一个新的。这将创建另一个非UI线程,可用于检查监视器是否被取消或更新某些状态变量或其他内容。

您忘记问问题了。你讲了一个故事,然后没问问题就停了下来。谢谢。我还有几个问题。如果你有时间,你能看一下吗?好的。我设法解决了我的问题。我将所有内容都放在syncExec()中,并使用作业调用我的long函数。然后等待作业完成,或按“取消”停止冻结的方法。