1

在运行后台任务之前,我可以取消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线程。

4

0 回答 0