热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SWT让耗时的操作后台运行

2019独角兽企业重金招聘Python工程师标准先上段有问题的代码:finalButtonbuttonnewButton(shell,SWT.CENTER);

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

先上段有问题的代码:

final Button button = new Button(shell, SWT.CENTER);
button.setText("抓取图像");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {final String wsdl = wsdlText.getText();final String trDate = trDateText.getText();final String flowId = flowIdText.getText();final String dest = saveText.getText();display.asyncExec(new Runnable() {public void run() {try {button.setText("处理中..");button.setEnabled(false);Main4Swt.start(wsdl, trDate, flowId, dest, bar, console);} catch (Exception e1) {console.setText(ErrorUtil.getError(e1));} finally {button.setText("抓取图像");button.setEnabled(true);}}});
}
});

我把整个button的事件处理代码都放到了display.asyncExec()中,但是运行以上代码还是会引起界面假死!这事让我抓狂

经过反复实践,得出如下实战步骤:
1. new一个Thread先
2. Thread中分三步走:
2.1 syncExec获取参数
2.2 try执行耗时操作
2.3 asyncExec处理后事

经过修改后的代码如下:

final Button button = new Button(shell, SWT.CENTER);
button.setText("抓取图像");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {new Thread() {String wsdl = null;String trDate = null;String flowId = null;String dest = null;public void run() {// [1]获取参数display.syncExec(new Runnable() {public void run() {wsdl = wsdlText.getText();trDate = trDateText.getText();flowId = flowIdText.getText();dest = saveText.getText();button.setText("处理中..");button.setEnabled(false);Swt.setLogText("");}});// [2]处理耗时操作try {Main4Swt ms = new Main4Swt();ms.start(wsdl, trDate, flowId, dest);} catch (Exception e1) {Swt.log(ErrorUtil.getError(e1), 2);}//[3]处理后事display.asyncExec(new Runnable() {public void run() {button.setText("抓取图像");button.setEnabled(true);}});}}.start();
}
});
注意第一段获得参数的代码是放在syncExec中而非asyncExec
这样做的原因是代码[2]必须在代码[1]执行完后(获得参数结束后)才能继续
最后,因为代码断[1]执行速度极快,可以将这段代码放在Thread之外,此时可以脱去syncExec的外套
最后的最后,invalid thread access的原因是你在thread中直接访问ui了组件,要么在thread之外访问,一旦在thread内访问ui, 就需要给上穿上asyncExec。

最后的最后的最后,shell也是ui,所以在thread内弹出一个对话框也要asynExec。

2013-08-24更新
在使用ProgressMonitorDialog的时候,代码要简化许多,但是参数forkable必须设置为true

ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(studio.getShell());
IRunnableWithProgress runnable = new IRunnableWithProgress() {public void run(final IProgressMonitor monitor){try{monitor.beginTask("xxxx",size);//handlemonitor.worked(1)//other UI resources except monitor should be wrapped up with asyncExecdisplay.asyncExec(new Runnable()){public void run(){MessageDialog.open(....)}}}finally{monitor.done();}}};
try {// It is recommended that fork is set to true in most cases.// If fork is set to false, the runnable will run in the UI thread// and it is the runnable's responsibility to call// Display.readAndDispatch() to ensure UI responsiveness.monitorDialog.run(true, true, runnable);
} catch (Throwable e) {Logger.error(e);
}


转载于:https://my.oschina.net/uniquejava/blog/91585


推荐阅读
author-avatar
少女24梦_276
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有