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