找回密码
 立即注册
首页 业界区 业界 C# Task 取消执行的简单封装

C# Task 取消执行的简单封装

均浇 2025-6-4 16:12:31
我让DeepSeek帮我写了一段使用 CancellationTokenSource 取消任务的简单示例如下:
取消任务的简单示例
  1. using System.Threading.Tasks;
  2. using System.Threading;
  3. public async Task Test()
  4. {
  5.     var cts = new CancellationTokenSource();
  6.     var task = Task.Run(() =>
  7.     {
  8.         while (true)
  9.         {
  10.             cts.Token.ThrowIfCancellationRequested();
  11.             Thread.Sleep(200);
  12.         }
  13.     });
  14.     await Task.Delay(1000);
  15.     cts.Cancel();
  16.     try
  17.     {
  18.         await task;
  19.     }
  20.     catch (OperationCanceledException)
  21.     {
  22.         // task is cancelled
  23.     }
  24.     finally
  25.     {
  26.         cts.Dispose();
  27.     }
  28. }
复制代码
相对于不可取消的普通任务多了很多代码,并且终止任务的方式 ThrowIfCancellationRequested 内部是通过抛出异常实现的
ThrowIfCancellationRequested 内部代码
  1. public void ThrowIfCancellationRequested()
  2. {
  3.     if (IsCancellationRequested)
  4.     {
  5.         throw new OperationCanceledExceptionEx(this);
  6.     }
  7. }
复制代码
于是我就想自己封装一个简单的包装类,代码如下:
CancelableTask
  1. namespace System.Threading.Tasks
  2. {
  3.     public sealed class CancelableTask : Task
  4.     {
  5.         readonly object cancelLock = new object();
  6.         CancellationTokenSource cts;
  7.         public bool IsCancellationRequested => cts != null && cts.IsCancellationRequested;
  8.         private CancelableTask(Action action, CancellationToken token) : base(action, token) { }
  9.         protected override void Dispose(bool disposing)
  10.         {
  11.             if (disposing)
  12.             {
  13.                 cts?.Dispose();
  14.             }
  15.             base.Dispose(disposing);
  16.         }
  17.         public void Cancel()
  18.         {
  19.             lock (cancelLock)
  20.             {
  21.                 if (!IsCompleted && !IsCancellationRequested)
  22.                 {
  23.                     cts.Cancel();
  24.                 }
  25.             }
  26.         }
  27.         public static CancelableTask StartNew(Action action)
  28.         {
  29.             var cts = new CancellationTokenSource();
  30.             var task = new CancelableTask(action, cts.Token);
  31.             task.cts = cts;
  32.             task.Start();
  33.             return task;
  34.         }
  35.         public static void Restart(ref CancelableTask task, Action action)
  36.         {
  37.             var oldTask = Interlocked.Exchange(ref task, null);
  38.             oldTask?.Cancel();
  39.             var newTask = StartNew(action);
  40.             Interlocked.Exchange(ref task, newTask);
  41.         }
  42.     }
  43. }
复制代码
此类公开了 Cancel 用来取消任务,静态的 StartNew 用来创建新实例,以及静态的 Restart 用来取消上个任务并重启任务,
还公开了一个 IsCancellationRequested 属性用来获取是否请求过取消任务,相对于调用 ThrowIfCancellationRequested 抛出异常来终止任务的方式性能更好也更加友好
使用此类重新编写上面的示例就简单很多了
CancelableTask 使用示例
  1. using System.Threading.Tasks;
  2. CancelableTask task;
  3. public async Task Test()
  4. {
  5.     task = CancelableTask.StartNew(() =>
  6.     {
  7.         while (!task.IsCancellationRequested)
  8.         {
  9.             Thread.Sleep(200);
  10.         }
  11.     });
  12.     await Task.Delay(1000);
  13.     task.Cancel();
  14.     await task;
  15. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册