C# 中通过CancellationTokenSource实现对超时任务的取消

我们在多线程中通常使用一个bool IsExit类似的代码来控制是否线程的运行与终止,其实使用CancellationTokenSource来进行控制更为好用,下面我们将介绍CancellationTokenSource相关用法。

C# 使用 CancellationTokenSource 终止线程

使用CancellationTokenSource对象需要与Task对象进行配合使用,Task会对当前运行的状态进行控制(这个不用我们关心是如何孔控制的)。而CancellationTokenSource则是外部对Task的控制,如取消、定时取消。

下面我们来看看示例代码

 
 
  1.     class Program
  2.     {
  3.         //声明CancellationTokenSource对象
  4.         static CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
  5.  
  6.         //程序入口
  7.         static void Main(string[] args)
  8.         {
  9.             Task.Factory.StartNew(MyTask, cancelTokenSource.Token);
  10.  
  11.             Console.WriteLine("请按回车键(Enter)停止");
  12.             Console.ReadLine();
  13.  
  14.             cancelTokenSource.Cancel();
  15.             
  16.             Console.WriteLine("已停止");
  17.             Console.ReadLine();
  18.         }
  19.  
  20.         //测试方法
  21.         static void MyTask()
  22.         {
  23.             //判断是否取消任务
  24.             while (!cancelTokenSource.IsCancellationRequested)
  25.             {
  26.                 Console.WriteLine(DateTime.Now);
  27.                 Thread.Sleep(1000);
  28.             }
  29.         }
  30.     }

运行效果如图

CancellationTokenSourceTask.Factory.StartNew 创建并启动了 MyTask 方法,并传递了一个 CancellationTokenSource.Token 对象进去。我们可以通过在外部CancellationTokenSource对象进行控制是否取消任务的运行

当在 MyTask 中的 cancelTokenSource.IsCancellationRequested 判断如果是取消了任务的话 就跳出while循环执行。也就结束了任务

 

我们还可以使用计时取消任务,当一个任务超过了我们所设定的时间然后自动取消该任务的执行。如下代码所示

 
 
  1.  var cancelTokenSource = new CancellationTokenSource(3000);

除了构造函数,我们还可以使用另外一种方式实现定时取消,如下代码所示

 
 
  1.  cancelTokenSource.CancelAfter(3000);

运行起来效果是一样的,3秒钟定时取消。

 

多个 CancellationTokenSource 复合

在有多个CancellationTokenSource需要一起并行管理的时候,比如任意一个任务取消 则取消所有任务。我们不必去一个一个的去关闭,只需要将需要一起并行关闭的CancellationTokenSource组合起来就行了。如下代码所示,执行结果是跟上面的图一样的。我就不再上图了。

 
 
  1.     class Program
  2.     {
  3.         //声明CancellationTokenSource对象
  4.         static CancellationTokenSource c1 = new CancellationTokenSource();
  5.         static CancellationTokenSource c2 = new CancellationTokenSource();
  6.         static CancellationTokenSource c3 = new CancellationTokenSource();
  7.  
  8.         //使用多个CancellationTokenSource进行复合管理
  9.         static CancellationTokenSource compositeCancel = CancellationTokenSource.CreateLinkedTokenSource(c1.Token, c2.Token, c3.Token);
  10.  
  11.         //程序入口
  12.         static void Main(string[] args)
  13.         {
  14.             Task.Factory.StartNew(MyTask, compositeCancel.Token);
  15.  
  16.             Console.WriteLine("请按回车键(Enter)停止");
  17.             Console.ReadLine();
  18.  
  19.             //任意一个 CancellationTokenSource 取消任务,那么所有任务都会被取消。
  20.             c1.Cancel();
  21.             
  22.             Console.WriteLine("已停止");
  23.             Console.ReadLine();
  24.         }
  25.  
  26.         //测试方法
  27.         static void MyTask()
  28.         {
  29.             //判断是否取消任务
  30.             while (!compositeCancel.IsCancellationRequested)
  31.             {
  32.                 Console.WriteLine(DateTime.Now);
  33.                 Thread.Sleep(1000);
  34.             }
  35.         }
  36.     }

以上代码调用了c1.Cancel();触发了MyTask()方法中的compositeCancel.IsCancellationRequested为true,则取消了任务。所以我们在所有任务中判断复合的这个CancellationTokenSource对象即可。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 .NET ,可以使用 CancellationTokenSource 和 Task.Delay 方法实现任务超时取消。 以下是一个示例,演示如何使用 CancellationTokenSource 和 Task.Delay 方法取消超时任务: ```csharp public async Task<int> DoAsyncOperation(CancellationToken cancellationToken) { // 模拟异步操作 await Task.Delay(5000, cancellationToken); return 42; } public async Task ExecuteAsyncOperation() { using (var cts = new CancellationTokenSource()) { // 设置超时时间 cts.CancelAfter(3000); try { // 启动异步操作 Task<int> task = DoAsyncOperation(cts.Token); // 等待异步操作完成 int result = await task; Console.WriteLine($"异步操作结果:{result}"); } catch (OperationCanceledException) { Console.WriteLine("异步操作已超时。"); } } } ``` 在上面的代码,我们首先定义了一个异步方法 DoAsyncOperation,它接受一个 CancellationToken 参数,并模拟一个长时间的异步操作。然后,我们定义了另一个方法 ExecuteAsyncOperation,它创建一个 CancellationTokenSource 对象,并调用 CancellationTokenSource.CancelAfter 方法设置超时时间。接下来,我们启动异步操作,并使用 await 等待操作完成。如果操作在超时时间内完成,我们输出操作结果。如果操作超时,我们捕获 OperationCanceledException 异常,并输出超时信息。 需要注意的是,在 DoAsyncOperation 方法,我们使用 Task.Delay 方法来模拟异步操作的延迟,并传递 CancellationToken 参数以监视取消请求。在 ExecuteAsyncOperation 方法,我们创建一个 CancellationTokenSource 对象,并调用 CancellationTokenSource.CancelAfter 方法来设置超时时间。然后,我们启动异步操作,并在任务完成或超时时捕获 OperationCanceledException 异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值