我有一个任务需要定期运行。我的第一个实现是这样的:
public static void CheckTask(CancellationTokenSource tokenSource)
{
do
{
// Do some processing
Console.WriteLine("Processing");
// Sleep awhile and wait for cancellation
// If not cancelled, repeat
} while (!tokenSource.Token.WaitHandle.WaitOne(1500));
Console.WriteLine("Bye bye");
}
此任务的启动方式如下:
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task task = null;
task = new Task((x)=> {
CheckTask(tokenSource);
//CheckTask2(t, (object)tokenSource);
}, tokenSource.Token);
task.Start();
然后我想与其循环执行任务,不如使用 ContinueWith 重新安排它呢?我的下一个实现是这样的:
public static void CheckTask2(Task task, object objParam)
{
CancellationTokenSource tokenSource = (CancellationTokenSource)objParam;
// Do some processing
Console.WriteLine("Processing");
// Sleep awhile and wait for cancellation
if(tokenSource.Token.WaitHandle.WaitOne(1500))
{
Console.WriteLine("Cancel requested");
return;
}
// Reschedule
task.ContinueWith(CheckTask2, tokenSource);
}
第二个实现更容易阅读和编写,我的测试显示没有区别,但我仍然想知道任务 ContinueWith 本身是否有缺点?
我仍然想知道任务是否有缺点继续 本身?
坦率地说,我发现您的代码附加了延续的可读性较差(但这只是基于风味的)。我看到的唯一缺点是您在令牌上使用WaitHandle
,这迫使您现在处置CancellationToken
对象:
访问此属性会导致实例化等待句柄。是的 最好只在必要时使用此属性,然后 在 最早的机会(处置源将处置此 分配的句柄)。手柄不应关闭或处置 径直。
相反,我发现带有Task.Delay
的模式更清晰易读:
public static async Task CheckTask(CancellationToken token)
{
do
{
// Do some processing
Console.WriteLine("Processing");
await Task.Delay(1500, token);
} while (!token.IsCancellationRequested);
Console.WriteLine("Bye bye");
}
然后当你想停止你的Task
,通过CancellationTokenSource
取消它。