即使将所有SWT代码包装在“ Display.getDefault().asyncExec
”中,我也无法更新UI。
假设我有一个监听器,称为单击一个按钮。
Listener enterlisner = new Listener() {
@Override
public void handleEvent(Event event)
{
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
try
{
if((event.keyCode == SWT.CR || event.keyCode == 13 || event.type == SWT.Selection) && btnAdd.isEnabled())
{
new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress()
{
@Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException
{
// method1()
// method2() {method2.1() , method2.2()}
// method3() {method3.1() , method3.2()}
// ....
// ...
// method10
}
});
}
}
catch (InvocationTargetException | InterruptedException e)
{
e.printStackTrace();
}
}
});
}
};
有人可以参考link并让我知道我哪里错了吗?
如何对在后台线程中运行的方法进行分叉?
最佳答案
当您已经在UI线程中时,将整个代码包装在asyncExec
中实际上什么都没有实现(除了一些非常专门的用途)。
您必须查看您的代码,并确定在后台线程中运行的每个片段。在那些地方,任何对UI操作的访问都必须使用asyncExec(或syncExec)调用。
传递给IRunnableWithProgress
的ProgressMonitorDialog
在后台线程中运行。因此,每次使用IRunnableWithProgress
代码访问任何UI对象时,都必须使用单独的asyncExec
或syncExec
调用。
所以像这样:
Listener enterlisner = new Listener() {
@Override
public void handleEvent(Event event)
{
if ((event.keyCode == SWT.CR || event.keyCode == 13 || event.type == SWT.Selection) && btnAdd.isEnabled())
{
new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress()
{
@Override
public void run(final IProgressMonitor monitor) throws IvocationTargetException, InterruptedException
{
... code not using UI
Display.getDefault().asyncExec(... code using UI ....);
... more code not using UI
Display.getDefault().asyncExec(... more code using UI ....);
}
}
}
}