我有一个关于Task的例子。我启动一个新的任务来执行一个LongTask并在我取消任务之后并在启动一个新任务后再次执行LongTask。但是TaskA运行不正常。它运行任务取消和新任务的工作。
如何立即运行新任务 并取消已取消的任务?
这是我的代码:
class Program
{
private static CancellationTokenSource tokenSource = new CancellationTokenSource();
static void Main(string[] args)
{
Program a = new Program();
Task.Factory.StartNew(() => a.LongTask(), tokenSource.Token);
Console.ReadLine();
//After enter
tokenSource.Cancel();
//Create new CancellationTokenSource to make Task continue run
tokenSource = new CancellationTokenSource();
Task.Factory.StartNew(() => a.LongTask(), tokenSource.Token);
Console.ReadLine();
}
public void LongTask()
{
StringBuilder display = new StringBuilder();
while (!tokenSource.IsCancellationRequested)
{
display.Append("1");
Console.WriteLine(display);
Thread.Sleep(1000);
}
}
}
答案 0 :(得分:2)
我将想象出第一个任务正在睡觉时会发生什么
while (!tokenSource.IsCancellationRequested)
{
display.Append("1");
Console.WriteLine(display);
Thread.Sleep(1000);
// tokenSource.Cancel();
// tokenSource = new CancellationTokenSource();
// Task.Factory.StartNew second task
}
然后在睡眠超时后,任务#1继续其循环以检查tokenSource.IsCancellationRequested
false
(因为此标记是新标记)。
现在您了解为什么两个任务以这种方式运行。让我们试试我的代码:
static void Main(string[] args)
{
var a = new Program();
var token = new CancellationTokenSource();
Task t1 = Task.Factory.StartNew(() => a.LongTask("#1", token1.Token), token1.Token);
Console.ReadLine();
token1.Cancel();
token = new CancellationTokenSource();
Task.Factory.StartNew(() => a.LongTask("#2", token2.Token), token2.Token);
Console.ReadLine();
}
public void LongTask(string name, CancellationToken killer)
{
var display = new StringBuilder();
while (!killer.IsCancellationRequested)
{
display.Append("1");
Console.WriteLine("{0} says: {1}",name, display);
Thread.Sleep(1000);
}
}
这里的技巧是为每个任务提供一个不同的令牌,而不是共享相同的静态令牌实例。