在Windows服务应用程序中,我启动了多个线程,如下所示:

class ConsumingEnumerableDemo
{
   // Demonstrates:
   //      BlockingCollection<T>.Add()
   //      BlockingCollection<T>.CompleteAdding()
   //      BlockingCollection<T>.GetConsumingEnumerable()
   public static void BC_GetConsumingEnumerable()
   {
       using (BlockingCollection<int> bc = new BlockingCollection<int>())
       {

           // Kick off a producer task
           Task.Factory.StartNew(() =>
           {
               for (int i = 0; i < 10; i++)
               {
                   bc.Add(i);
                   Thread.Sleep(100); // sleep 100 ms between adds
               }

               // Need to do this to keep foreach below from hanging
               bc.CompleteAdding();
           });

           // Now consume the blocking collection with foreach.
           // Use bc.GetConsumingEnumerable() instead of just bc because the
           // former will block waiting for completion and the latter will
           // simply take a snapshot of the current state of the underlying collection.
           foreach (var item in bc.GetConsumingEnumerable())
           {
               Console.WriteLine(item);
           }
        }
      }
    }

如果我想停止任务,该怎么办?
我听说过“取消 token ”,但不确定如何将其应用于案件。

最佳答案

只需定义一个Cancellation Token Source

var cts = new CancellationTokenSource();

并像这样使用它:
 Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                bc.Add(i);
                Thread.Sleep(100); // sleep 100 ms between adds
                cts.ThrowIfCancellationRequested();
            }

            // Need to do this to keep foreach below from hanging
            bc.CompleteAdding();
        },cts.Token);

当您想取消任务时,请使用:
cts.Cancel();

另外,您可能想看看这些博客文章:
  • Parallel Programming: Task Cancellation
  • Async in 4.5: Enabling Progress and Cancellation in Async APIs
  • 10-08 14:33