Почему мой Swingworker отменяет свою ветку только в первый раз? - PullRequest
0 голосов
/ 26 февраля 2011

У меня есть Swingworker, который мне иногда нужно отменить. Если я выполняю и затем отменяю, это работает как ожидалось. Если я запускаю новый экземпляр этого Swingworker и затем пытаюсь отменить его, вызывается функция отмены, она возвращает истину, но метод doInBackground выполняется полностью без отмены. Под полностью я подразумеваю цикл while в функции, выполняемой потоком Swingworker, завершается (которую я могу отменить только в первый раз).

Дайте мне знать, если я разъясню свою проблему, это такое странное поведение, что я просто не могу понять.

Вот мой код:

protected void firePlayButtonPlotWorker() {
    /*Cancel any previous plotWorker threads that may be running. The user might click the play
     * button again, so we ignore that if the thread isn't finished.*/
    if(plotWorker != null && !plotWorker.isDone())
    {
        System.err.println("Cancelling plot thread");
        plotWorker.cancel(true);
    }


    /*Create a SwingWorker so that the computation is not done on the Event Dispatch Thread*/
    plotWorker = new SwingWorker<Void, Void>() 
    {
        @Override
        public Void doInBackground() 
        {

            System.err.println("Plot Swing Worker Thread starting");
            playAudio(sceneManager.getScenes()); //Computation that requires an asynchronous while loop
            System.err.println("Plot Swing Worker Thread ended");
            return null;
        }

        @Override
        public void done() 
        {
            plotWorker = null;
        }
    };


    plotWorker.execute();
}

public void handleAudioEvent(AudioState audioState)
{
    switch (audioState)
    {
    case PLAY:
        firePlayButtonPlotWorker();
        break;
    case PAUSE:
        if(plotWorker != null)
        {
            boolean cancelBool = plotWorker.cancel(true);
            System.out.println("Cancelled? " + cancelBool);
        }
        break;
    case STOP:
        if(plotWorker != null)
        {
            plotWorker.cancel(true);
        }
        audioPlayerMarkerBean.setMarkerLocation(0);
        double[] coord = {0.0, 0.0};
        marker.drawMarker(coord);
        break;
    }
}

1 Ответ

2 голосов
/ 26 февраля 2011

Вызов отмены со значением true в качестве аргумента прервет поток, используя метод Thread.interrupt .

Так что, если ваш поток ожидает, спит или присоединяется, будет выдано исключение InterruptedException.Иначе, статус прерывания потока будет установлен.

Если вы проглотите InterruptedException, поток продолжится до конца.Если поток работает (то есть не ждет, не спит или не присоединяется), когда он прерван, он также продолжит работу.Вы должны регулярно проверять прерванный статус потока (используя Thread.currentThread.isInterrupted()) в фоновой задаче и прекратить выполнение, как только он вернет true.

...