0

我有一个应用程序从我那里获取所有添加的文件Listbox并播放这些文件:

IEnumerable<string> source

public void play()
{
    Task.Factory.StartNew(() =>
    {
        Parallel.ForEach(source,
                         new ParallelOptions
                         {
                             MaxDegreeOfParallelism = 1 //limit number of parallel threads 
                         },
                         file =>
                         {
                              //each file process via another class
                         });
    }).ContinueWith(
            t =>
            {
                OnFinishPlayEvent();
            }
        , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
        );
    }

我的处理文件可以通过我的类属性停止,但如果我想停止所有等待的文件,我该怎么做?

4

2 回答 2

1

你需要设计你的例程来接受一个CancellationToken,然后触发一个CancellationTokenSource.Cancel()

这将允许您提供一种机制来合作取消您的工作。

有关详细信息,请参阅MSDN 上的托管线程中的取消和任务取消

于 2013-06-03T15:47:49.130 回答
0

如果要停止并行循环,请使用ParallelLoopState该类的实例。要取消任务,您需要使用CancellationToken. 由于您将并行循环嵌入到任务中,因此您可以简单地将取消令牌传递到任务中。请记住,如果您选择等待您的任务,这将引发您必须捕获的 OperationCanceledException。

例如,为了论证,我们假设其他东西会在你的类中调用一个委托来设置取消令牌。

CancellationTokenSource _tokenSource = new CancellationTokenSource();

//Let's assume this is set as the delegate to some other event
//that requests cancellation of your task
void Cancel(object sender, EventArgs e)
{
  _tokenSource.Cancel();
}

void DoSomething()
{
  var task = Task.Factory.StartNew(() => { 
    // Your code here...
  }, _tokenSource.Token);

  try {
    task.Wait();
  }
  catch (OperationCanceledException) {
    //Carry on, logging that the task was canceled, if you like
  }
  catch (AggregateException ax) {
    //Your task will throw an AggregateException if an unhandled exception is thrown
    //from the worker. You will want to use this block to do whatever exception handling
    //you do.
  }
}

请记住,有更好的方法可以做到这一点(我在这里从记忆中输入,所以可能会有一些语法错误等),但这应该让你开始。

于 2013-06-03T17:24:26.920 回答