Eclipse RCP中IProgressMonitor的isCanceled()点击取消按钮后不触发问题
Eclipse进度条对话框取消按钮无响应问题修复方案
现有代码直接修复方案
取消按钮无响应的核心原因是ProgressMonitorDialog.run()的第一个参数fork设为了false,代表任务直接在UI线程执行,UI线程被任务逻辑占满时,取消按钮的点击事件无法被分发处理,因此monitor.isCanceled()永远返回false。
仅需修改run方法的第一个参数为true即可修复,此时任务会在独立非UI线程执行,取消事件可以正常响应:
// 仅修改第一个参数为true,其余逻辑保持不变 pmd.run(true, true, rwp);
注意:如果
mapper.mapProfile方法中存在UI操作,需要用Display.getDefault().asyncExec()包裹UI逻辑,避免非UI线程操作UI报错。
Job实现方案(支持参数传递)
自定义Job子类时,通过构造方法传入需要的profile、list、notification等参数即可,实现代码如下:
1. 自定义带参数的Job子类
public class MapperRunJob extends Job { // 声明业务需要的所有参数 private final EObject profile; private final EObject list; private final Notification notification; private final YourBrokerType broker; // 替换为你实际的broker类类型 // 构造方法传入所有参数 public MapperRunJob(EObject profile, EObject list, Notification notification, YourBrokerType broker) { super("Loading DG list configurations"); this.profile = profile; this.list = list; this.notification = notification; this.broker = broker; // 配置Job属性 setUser(true); setCancelable(true); } @Override protected IStatus run(IProgressMonitor monitor) { broker.stopNotification(); try { if (mappers.get(profile) == null) { return Status.OK_STATUS; } int workload = mappers.get(profile).size(); monitor.beginTask(getName(), workload); Pattern pattern = Pattern.compile("ProfileTo(.*?)ViewMapper"); for (final ProfileToDgListViewMapper mapper : mappers.get(profile)) { // 前置判断取消,提前终止循环 if (monitor.isCanceled()) { System.out.println("Heloooooooooo"); return Status.CANCEL_STATUS; } Matcher matcher = pattern.matcher(mapper.toString()); if (matcher.find()) { monitor.subTask("Loading DG list configuration section " + matcher.group(1)); } mapper.mapProfile(profile, list, notification); monitor.worked(1); } return Status.OK_STATUS; } finally { monitor.done(); // 无论任务正常完成/取消/异常,都恢复通知 broker.continueNotification(); } } }
2. 调用Job的代码
public void runMappers(final EObject profile, final EObject list, final Notification notification) { this.notification = notification; // 实例化自定义Job,传入所有参数后启动即可 MapperRunJob job = new MapperRunJob(profile, list, notification, getBroker()); job.schedule(); }
内容的提问来源于stack exchange,提问作者Suraj Dighodkar
相关产品推荐
相关产品推荐

