我有一个Task
s的延续链,可能会被取消,比如发生超时。我想确定取消发生时哪个任务正在运行。这里就是我说的:取消后继续链中的哪个任务正在运行?
CancellationTokenSource cts = new CancellationTokenSource();
Task timeoutTask = Task.Delay(5000).ContinueWith((t) => cts.Cancel());
Task workChain = Task.Factory.StartNew((t) =>
{
Console.WriteLine("Running task " + Task.CurrentId);
Thread.Sleep(1000);
}, -1, cts.Token);
Task parent = workChain;
for (int i = 0; i < 10; i++)
{
parent = parent.ContinueWith((t, o) =>
{
Console.WriteLine("Running task " + Task.CurrentId);
Console.WriteLine("Last Task.AsyncState = " + t.AsyncState);
Thread.Sleep(1000);
}, i, cts.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
}
parent.ContinueWith((t) =>
{
Console.WriteLine("Cancel task " + Task.CurrentId);
Console.WriteLine("Last running Task.AsyncState = " + t.AsyncState);
}, TaskContinuationOptions.OnlyOnCanceled);
当我运行上面,传递到OnlyOnCanceled
一个先行词是不是当事情被取消时正在运行的任务。我知道为什么:OnlyOnCanceled
任务是父节点由循环中创建的最后一个任务派生,并且当发生超时时,所有未完成的任务都被标记为取消而未启动。
让每个任务检查令牌的状态并在其他地方存储其他地方的工作,但是在下一个任务开始之前,一个任务完成后发生取消的可能性很小。在那种情况下,我没有发现任何关于第一个被取消的任务。当任务开始时,我可以随时存储一些东西,如果取消了,我可以存储其他东西,但是这很快就会感觉到非常糟糕。
所以,你说你想知道取消发生时哪个任务正在运行,但正如你所说的那样,它可能不是。取消可能会在一个结束后和下一个开始之前发生。你想知道成功完成的最后一项任务,或者*没有成功完成的第一项任务吗? – Servy
注意,如果您希望CTS在5000毫秒内取消任务,只需在CTS构造函数中放入5000;比你所做的更简单。 – Servy
为什么使用'ContinueWith()'而不是'await'?你为什么使用'Task'链而不是一个带有循环的'Task'? – svick