使用 ContinueWith 自继续任务
Self continuing Task using ContinueWith
我有一项任务需要定期 运行。我的第一个实现是这样的:
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 本身是否有缺点?
I still wonder if there are drawbacks for a task to ContinueWith
itself?
坦率地说,我发现你的代码在附加延续的情况下可读性较差(但这只是基于风味)。我看到的唯一缺点是你在令牌上使用了 WaitHandle
,这迫使你现在 dispose your CancellationToken
object:
Accessing this property causes a WaitHandle to be instantiated. It is
preferable to only use this property when necessary, and to then
dispose the associated CancellationTokenSource instance at the
earliest opportunity (disposing the source will dispose of this
allocated handle). The handle should not be closed or disposed
directly.
相反,我发现 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
取消它。
我有一项任务需要定期 运行。我的第一个实现是这样的:
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 本身是否有缺点?
I still wonder if there are drawbacks for a task to ContinueWith itself?
坦率地说,我发现你的代码在附加延续的情况下可读性较差(但这只是基于风味)。我看到的唯一缺点是你在令牌上使用了 WaitHandle
,这迫使你现在 dispose your CancellationToken
object:
Accessing this property causes a WaitHandle to be instantiated. It is preferable to only use this property when necessary, and to then dispose the associated CancellationTokenSource instance at the earliest opportunity (disposing the source will dispose of this allocated handle). The handle should not be closed or disposed directly.
相反,我发现 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
取消它。