在运行后台任务之前,我可以取消Swingworker
并等待它完成吗?或者,我可以向运行代码的任务发送中断doInBackground()
而不取消整个摇摆工人。?
我的问题是我不希望在代码完成done()
之前启动代码doInBackground()
。早期的代码从未调用过取消,Swingworker
而是我只是设置了一个可变布尔值,WidgetController
它将检查并且如果设置为正常关闭。这一切都很好,除了WidgetController
有时需要很长时间来检查这个标志,所以我需要能够使用中断方法。
伪示例
当用户单击启动时会显示一个对话框,此调用WidgetDialogListener
此创建实例WidgetWorker
,此启动WidgetController
,显示一个WidgetProgressDialog
并在显示正常完成时WidgetController
显示所做操作ShowWidgetReport
的摘要WidgetController
。
运行WidgetController
时,WidgetProgressDialog
会显示进度。如果用户单击取消按钮以停止进度,这会导致发送中断,WidgetController
然后无需等待widgetcontroller
实际完成 ,就会调用 done 方法导致ShowWidgetReport
显示。但我不希望它在WidgetController
实际完成之前这样做。
class WidgetDialogListener implements ActionListener
{
public WidgetDialogListener()
{
}
public void actionPerformed(ActionEvent e)
{
StartFixSongsDialog.this.dispose();
WidgetProgressDialog wpd = new FixSongsDialog();
wpd.setVisible(true);
WidgetWorker ww = new WidgetWorker();
wpd.setSwingWorker(ww);
Executors.newSingleThreadScheduledExecutor().submit(ww);
}
}
class WidgetProgressDialog
{
....................
private void actionPerformed(ActionEvent e)
{
//Main.stopTask();
swingWorker.cancel(true);
}
}
class WidgetWorker extends SwingWorker<String, Object>
{
@Override
public String doInBackground() throws Exception
{
new WidgetController().startCreateWidgets();
return "";
}
@Override
protected void done()
{
ShowWidgetReport showReport = new ShowWidgetReport();
showReport.setVisible(true);
}
}
编辑
我使用了Waiting for a cancelled future 中的AwaitingWorker
描述来真正完成Jacob 指给我的
abstract class AwaitingWorker<T, V> extends SwingWorker<T, V>
{
private final CountDownLatch actuallyFinishedLatch = new CountDownLatch(1);
protected abstract T performOperation() throws Exception;
@Override
protected final T doInBackground() throws Exception
{
try
{
return performOperation();
}
finally
{
actuallyFinishedLatch.countDown();
}
}
public void awaitActualCompletion() throws InterruptedException
{
actuallyFinishedLatch.await();
}
}
class WidgetWorker extends AwaitingWorker<String, Object>
{
@Override
public String performOperation() throws Exception
{
new WidgetController().startCreateWidgets();
return "";
}
@Override
protected void done()
{
try
{
awaitActualCompletion();
}
catch(InterruptedException ioe)
{
}
ShowWidgetReport showReport = new ShowWidgetReport();
showReport.setVisible(true);
}
}
也许完全误解了解决方案,但似乎无论您采用哪种方式,gui 线程最终都会等待非 gui 任务完成,而我想要的是在完成任何操作之前完成非 gui 任务gui线程。