使用 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 取消它。