最佳实践:长时间运行任务的创建

29

这个后台线程的设计是否适用于在 .Net 4 中使用任务 API 运行? 我唯一担心的是,如果我们想要取消该任务,我该怎么做? 我知道可以将 ProgramEnding 设置为 true,但是我知道任务 API 中有一个 CancellationToken

这只是一个示例代码,因此一个线程将添加到集合中,另一个线程将从集合中删除。 该任务被设置为长时间运行,因为它需要在程序运行时持续运行。

private void RemoveFromBlockingCollection()
{
    while (!ProgramEnding)
    {
       foreach (var x in DataInQueue.GetConsumingEnumerable())
       {
          Console.WriteLine("Task={0}, obj={1}, Thread={2}"
                          , Task.CurrentId, x + " Removed"
                          , Thread.CurrentThread.ManagedThreadId);
       }
    }
}

private void button1_Click(object sender, EventArgs e)
{
   DataInQueue = new BlockingCollection<string>();
   var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection
                                 , TaskCreationOptions.LongRunning);

   for (int i = 0; i < 100; i++)
   {
     DataInQueue.Add(i.ToString());
     Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
                       Task.CurrentId, i + " Added", 
                       Thread.CurrentThread.ManagedThreadId);
     Thread.Sleep(100);
   }
   ProgramEnding = true;
}

更新:我发现可以去掉ProgramEnding布尔变量,使用DataInQueue.CompleteAdding将线程结束。

1个回答

26

正如你已经提到的,你可以使用CancellationToken。这样做:

var cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew(RemoveFromBlockingCollection
                      , TaskCreationOptions.LongRunning
                      , cancellationTokenSource.Token);  

然后在您的代码中,您可以使用以下方法取消任务:

cancellationTokenSource.Cancel();

在你的长时间运行的任务中,你可以查询令牌,以确定是否有取消请求:

if (cancellationTokenSource.Token.IsCancellationRequested)

是的,这将有效。或者您可以使用我上面提到的CancellationToken。 - Fischermaen
只是一个提示。StartNew方法不接受CancellationTokenSource,只接受CancellationToken。 - Jon
@Jon ... 那就是我所知道的。所以我把.Token作为参数提供了。;-) - Fischermaen
17
我看不到你在TaskFactory文档中使用的StartNew方法的方法签名(http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory(v=vs.110).aspx)。唯一还带有TaskCreationOptions和CancellationToken参数的StartNew方法也需要一个TaskScheduler参数。 - Matt Becker
这个线程的普遍共识是:https://dev59.com/Y2s05IYBdhLWcg3wQvyq 最好的退出正在运行的任务的方法是调用CancellationTokenSource.Token.ThrowIfCancellationRequested()。 - Sudhanshu Mishra
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接