2013-01-11 2 views
0

У меня есть слушатель операций, который запускает и запускает Thread A. Когда операция завершает остановку Thread A и закрывается диалоговое окно.Остановка потока B, когда поток A останавливается

Я создал простой индикатор выполнения, который НЕИЗВЕСТНО. В основном, потому что нет возможности получить среднее время работы. Время зависит от разных факторов. Итак, я установил TOTAL_TIME достаточно высоким.

Я хотел бы как-то остановить стопку Progress Bar прямо перед закрытием диалогового окна.

ProgressBarThread

class ProgressBarThread implements IRunnableWithProgress { 
    private static final int TOTAL_TIME = 5000; 
    private static final int INCREMENT = 1000; 

    public ProgressBarThread() { 

    } 

    public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException { 
    monitor.beginTask("Sending Plot", IProgressMonitor.UNKNOWN); 
    for (int total = 0; total < TOTAL_TIME ; total += INCREMENT) { 
     Thread.sleep(INCREMENT); 
     monitor.worked(INCREMENT); 
     if (total == TOTAL_TIME/2) monitor.subTask("Please be patient... Operation should finish soon."); 
    } 
    monitor.done(); 

    } 

OperationListener - закрывает окно, когда операция возвращает

public abstract class MyOperationListener implements InterfaceAIFOperationListener { 

    AplotPlotterDialog w = null; 

    public MyOperationListener(AplotPlotterDialog win) { 
    w = win; 
    } 

    public void startOperation(String startMessage) { 
    Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
      w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT)); 
      w.recursiveSetEnabled(getShell(), getShell().getEnabled()); 
      w.getShell().setEnabled(!getShell().getEnabled()); 
     } 
    }); 
    } 

    public void endOperation() { 
    try { 
     endOperationImpl(); 
    } 
    finally { 
     Display.getDefault().asyncExec(new Runnable() { 
      public void run() { 
       w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); 
       w.recursiveSetEnabled(getShell(), true); 
       w.getShell().setEnabled(!getShell().getEnabled()); 
       w.close(); 
      } 
     }); 
    } 
    } 
    abstract protected void endOperationImpl(); 

}

метод для запуска ProgressBar

public void startProgressBar() { 
    try { 
    new ProgressMonitorDialog(getShell()).run(true, false, 
     new ProgressBarThread()); 
    } 
    catch (InvocationTargetException e) { 
    MessageDialog.openError(getShell(), "Error", e.getMessage()); 
    } 
    catch (InterruptedException e) { 
    MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage()); 
    } 

}

Метод работы и где начинается ProgressBar

public void startPrintOperation() { 
    Display.getDefault().asyncExec(new Runnable() { 
    public void run() { 
     startProgressBar(); 
    } 
    }); 
    final ArrayList<PlotData> datasetData = AplotPlotDataModel.getInstance().getPlotDataArray(); 
    plotOp = new AplotPlotOperation(appReg.getString("aplot.message.PLOTTING"),datasetData, getPlottersData(), getSpinnerValue(), session); 
    plotOp.addOperationListener(new MyOperationListener(this) { 
    public void endOperationImpl() { 
     try { 
      plotResults = (ArrayList) plotOp.getPlotResults(); 
      for (int i = 0; i < plotResults.size(); ++i) { 
          AplotResultsDataModel.getInstance().addEntry((AplotPlotResultsParser.DatasetPlotResult) plotResults.get(i)); 
      } // end for 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     finally { 
      plotOp.removeOperationListener(this); 
      plotOp = null; 
      Display.getDefault().asyncExec(new Runnable() { 
       public void run() { 
       baseDialog.removeAllTableRows(); 
       AplotPlotDataModel.getInstance().clearPlotDataArray(); 
       } 
      }); 
     } 
    } 
    }); 
    session.queueOperation(plotOp); 
} 

--------------------- --- РЕДАКТИРОВАТЬ ------------------

Вот как я пытаюсь реализовать предложение @Serious.

Изменения, сделанные в ProgressBar класса

class ProgressBarThread implements IRunnableWithProgress { 
    private static final int TOTAL_TIME = 10000; 
    private static final int INCREMENT = 1000; 
    private Condition done = null; 

    public ProgressBarThread(Condition done) { 
    this.done = done; 
    } 

    public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException { 
    monitor.beginTask("Creating PDF File(s)", IProgressMonitor.UNKNOWN); 
    for (int total = 0; total < TOTAL_TIME ; total += INCREMENT) { 
     if (done.await(INCREMENT, TimeUnit.MILLISECONDS)) 
     { 
      break; 
     } 
     monitor.worked(INCREMENT); 
     if (total == TOTAL_TIME/2) monitor.subTask("Please be patient... Operation should finish soon."); 
    } 
    monitor.done(); 
    } 
} 

Это изменения в MyOperationLisnter класса

public abstract class MyOperationListener implements InterfaceAIFOperationListener { 
    AplotCreatePDFDialog w = null; 
    Condition done = null; 

    public MyOperationListener(AplotCreatePDFDialog win) { 
    w = win; 
    Lock lock = new ReentrantLock(); 
    done = lock.newCondition(); 
    } 

    public void startOperation(String startMessage) { 
    Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
    startProgressBar(); 
     } 
    }); 
    } 

    public void startProgressBar() { 
    try { 
     new ProgressMonitorDialog(getShell()).run(true, false, 
     new ProgressBarThread(done)); 
    } 
    catch (InvocationTargetException e) { 
     MessageDialog.openError(getShell(), "Error", e.getMessage()); 
    } 
    catch (InterruptedException e) { 
     MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage()); 
    } 
    } 

    public void endOperation() { 
    try { 
     endOperationImpl(); 
    } 
    finally { 
     Display.getDefault().asyncExec(new Runnable() { 
      public void run() { 
       w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); 
       w.recursiveSetEnabled(getShell(), true); 
       w.getShell().setEnabled(!getShell().getEnabled()); 
       done.signal(); 
       w.close(); 
      } 
     }); 
    } 
    } 
    abstract protected void endOperationImpl(); 
} 

я удалить метод startProgressBar из Dialiog класса. Я также удалил startProgressBar от метода, который запускает операцию Listener

private void startSavePdfOperation() { 
    //Display.getDefault().asyncExec(new Runnable() { 
    // public void run() { 
    //  startProgressBar(); 
    // } 
    //}); 
    saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session); 
    saveOp.addOperationListener(new MyOperationListener(this) {<-- this is the start operation listener call. 

Результаты: Я получаю диалоговое окно ошибки вместо ProgressBar диалога. Я также получаю следующую ошибку замерзает

enter image description here

и прикладными.

+0

Обычный способ остановки индикатора выполнения состоит в том, чтобы индикатор выполнения отображал переменную, которая была изменена другим потоком, и цикл цикла выполнения завершается, если его значение изменилось. –

ответ

0

Вы могли бы ждать состояния:

class ProgressBarThread implements IRunnableWithProgress 
{ 
    private static final int TOTAL_TIME = 5000; 
    private static final int INCREMENT = 1000; 

    private Condition done = null; 

    public ProgressBarThread(Condition done) 
    { 
     this.done = done; 
    } 

    public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException 
    { 
     monitor.beginTask("Sending Plot", IProgressMonitor.UNKNOWN); 
     for (int total = 0; total < TOTAL_TIME ; total += INCREMENT) 
     { 
      if (done.await(INCREMENT, TimeUnit.MILLISECONDS)) 
      { 
       break; 
      } 
      monitor.worked(INCREMENT); 
      if (total == TOTAL_TIME/2) monitor.subTask("Please be patient... Operation should finish soon."); 
     } 
     monitor.done(); 
    } 
} 

условие создается основной процесс:

AplotPlotterDialog w = null; 

Condition done = null; 

public MyOperationListener(AplotPlotterDialog win) 
{ 
    w = win; 
    Lock lock = new ReentrantLock(); 
    done = lock.newCondition(); 
} 

public void startProgressBar() 
{ 
    try 
    { 
     new ProgressMonitorDialog(getShell()).run(true, false, 
     new ProgressBarThread(done)); 
    } 
    catch (InvocationTargetException e) 
    { 
     MessageDialog.openError(getShell(), "Error", e.getMessage()); 
    } 
    catch (InterruptedException e) 
    { 
     MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage()); 
    } 
} 

public void endOperation() 
{ 
    try 
    { 
     endOperationImpl(); 
    } 
    finally 
    { 
     Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
     w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); 
     w.recursiveSetEnabled(getShell(), true); 
     w.getShell().setEnabled(!getShell().getEnabled()); 
     done.signal(); 
     w.close(); 
    } 
    }); 
    } 
} 

Хотя операция продолжается поведение будет таким же как ваш текущая версия.

Но когда основной процесс будет выполнен, он будет уведомлять, сигнализируя о состоянии, полосу хода выполнения, которая немедленно выйдет из цикла.

+0

MyOperationListener должен иметь метод StarOperation - вы заменили его на StartProgressBar. Должен ли я делать что-то вроде startOperation() {startProgressBar}? – jkteater

+0

Мне очень нравится идея состояния. См. Мое редактирование выше и посмотреть, где у меня проблема. благодаря – jkteater

Смежные вопросы