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函数。然后等待作业完成,或按“取消”停止冻结的方法。