2013-06-03 2 views
0

У меня есть приложение, которое принимает все добавленные файлы из списка и воспроизводит этот файл.Отменить мою параллельную петлю задачи

это класс, который принимает IEnumerable<string> source и воспроизводить файлы с помощью другого класса:

public CancellationTokenSource _tokenSource { get; set; } 
private IEnumerable<string> _source; 

    public void play(PacketDevice selectedOutputDevice, double speed, int parallelThreads) 
    { 
     var token = _tokenSource.Token; 
     if (token.IsCancellationRequested) 
     { 
      return; 
     } 

     Task.Factory.StartNew(() => 
     { 
      try 
      { 
       Parallel.ForEach(_source, 
        new ParallelOptions 
        { 
         MaxDegreeOfParallelism = 1; 
        }, 
        file => 
        { 
         processFile(file, selectedOutputDevice, speed, parallelThreads); 
         //token.ThrowIfCancellationRequested(); 
        }); 
      } 
      catch (AggregateException) 
      { 

      } 

     }, _tokenSource.Token).ContinueWith(
       t => 
       { 
        OnFinishPlayEvent(); 
       } 
      , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread 
      ); 
    } 

И от основной формы при Стоп нажатии кнопки события я изменить _tokenSource.Cancel();, но моя проблема в том, что мой цикл продолжает работать и не останавливаться.

+0

Можете ли вы продемонстрировать это в короткой, но полной программе? Это действительно выглядит так * должно * работать. Он не отменяет текущие задачи обработки, но он должен избегать запуска каких-либо новых ... Это предполагает, что вы действительно получаете код отмены. Вызов 'Task.WaitAll' зловещий ... вы уверены, что это не просто блокировка? –

+1

На самом деле, вы не передаете какие-либо задачи в 'Task.WaitAll', поэтому я не думаю, что он делает что-либо * - вы должны избавиться от всего блока try/catch, чтобы избежать путаницы. –

+0

Связанный с вами вопрос: http://stackoverflow.com/questions/16900703/stop-my-task-and-all-my-waiting-task, похоже, очень сильно перекрывается с этим. – usr

ответ

1

Вам нужно обрабатывать запрос отменить вручную в Parallel.ForEach:

var token = _tokenSource.Token; 

Parallel.ForEach(_source, 
    new ParallelOptions 
    { 
     MaxDegreeOfParallelism = 1//limit number of parallel threads 
    }, 
    file => 
    { 
     //here i am process my file via another class 

     // Cancel if required 
     token.ThrowIfCancellationRequested(); 
    }); 

Это, как говорится, если вы собираетесь установить MaxDegreeOfParallelism = 1, нет никаких оснований для использования Parallel.ForEach, как это будет эффективно работать последовательно.

+0

MaxDegreeOfParallelism = 1 только для этого времени, потому что я использую несколько обычно – user2214609

+0

Он работает, но имеет исключение OperationCanceledException, и если я помещаю код внутри Try Catch, он не останавливается – user2214609

+0

@ user2214609 Wrap * only * Parallel.ForEach в обработчике исключений , а не весь блок. Тогда это поймает исключение отмены. –

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