对于需要使用.Net 4中的Task API运行的后台线程,这是一个很好的设计吗?我唯一担心的是,如果我们要取消该任务,我将如何做到这一点?我知道我可以将ProgramEnding
设置为true
,但我知道任务API中有CancellationToken
。
这只是一个示例代码示例,以便一个线程将添加到一个集合,另一个线程将从中删除。任务设置为LongRunning,因为这需要在程序运行时连续运行
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;
}
UPDATE:我发现我可以删除ProgramEnding布尔值并使用DataInQueue.CompleteAdding来结束线程。
答案 0 :(得分:20)
正如您已经提到的,您可以使用CancellationToken。这样做:
var cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew(RemoveFromBlockingCollection
, TaskCreationOptions.LongRunning
, cancellationTokenSource.Token);
稍后在您的代码中,您可以使用以下命令取消任务:
cancellationTokenSource.Cancel();
在长时间运行的任务中,如果要求取消,您可以询问令牌:
if (cancellationTokenSource.Token.IsCancellationRequested)