在自动化设备动作流程中,人为任意想取消当前动作,常见方法是使用全局变量,实时检测变量决定退出。这里介绍一个System.Threading空间下的 CancellationTokenSource类,他可以设置超时,设置信息等封装
基本使用超时和手动设置退出
CancellationTokenSource:用于控制和生成CancellationToken
CancellationToken:取消令牌,可以注册取消回调等操作
1、先实例化CancellationTokenSource
2、注册取消回调
3、启动一个Task,模拟耗时操作
4.调用CancellationTokenSource的CancelAfter方法,表示多少毫秒后取消,也可使用Cancel方法立即取消
5、IsCancellationRequested属性判断任务是否取消,没取消则一直输出i
抛出异常退出
以下举例 async await的异步使用,用到CancellationToken来取消任务,并手动设置抛异常传达信息
[HttpGet]
public async Task<IActionResult> CancelDownLoad(CancellationToken cancellationToken)
{
try
{
var _client = _httpClient.CreateClient("bigDownLoad");
_client.DefaultRequestHeaders.Range = new RangeHeaderValue(0, 1024 * 1024 * 50);
await Task.Delay(1000);
if (!cancellationToken.IsCancellationRequested)
{
var resp = await _client.GetAsync("http://du.cainiaoxt.cn/dd.php/windows_7_ultimate_x64_2023.iso",cancellationToken);
if (resp.StatusCode != System.Net.HttpStatusCode.OK)
{
string chunkFileFolder = @"D:\";
string bigFileName = chunkFileFolder + @"\bigFile" + new Random().Next(0, 10);
using (FileStream fs = new FileStream(bigFileName, FileMode.Create))
{
var respStream = await resp.Content.ReadAsStreamAsync();
await respStream.CopyToAsync(fs);
await respStream.FlushAsync();
}
}
return Ok();
}
else
{ // 设置抛异常退出
cancellationToken.ThrowIfCancellationRequested();
return BadRequest("下载任务取消!");
}
}
catch (OperationCanceledException ex)
{
Console.WriteLine("下载任务取消!"+ex.Message);
return BadRequest("下载任务取消!");
}
}
关联退出
另外可以设置退出链接,多个关联全部退出
// See https://aka.ms/new-console-template for more information
CancellationTokenSource cts=new CancellationTokenSource();
cts.Token.Register(() => { Console.WriteLine("任务1已停止"); });
CancellationTokenSource cts2 = new CancellationTokenSource();
cts2.Token.Register(() => { Console.WriteLine("任务2已停止"); });
CancellationTokenSource cts3 = new CancellationTokenSource();
cts3.Token.Register(() => { Console.WriteLine("任务3已停止"); });
var linkTokenSource=CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cts2.Token, cts3.Token);
linkTokenSource.Token.Register(() => { Console.WriteLine("关联token取消"); });
Task.Run(() =>
{
int i = 1;
while (!cts.IsCancellationRequested)
{
i++;
Console.WriteLine("任务1:"+i);
Task.Delay(500).Wait();
}
});
Task.Run(() =>
{
int i = 1;
while (!cts2.IsCancellationRequested)
{
i++;
Console.WriteLine("任务2:"+i);
Task.Delay(500).Wait();
}
});
Task.Run(() =>
{
int i = 1;
while (!cts3.IsCancellationRequested)
{
i++;
Console.WriteLine("任务3:"+i);
Task.Delay(500).Wait();
}
});
Task.Run(() =>
{
int i = 1;
while (!linkTokenSource.IsCancellationRequested)
{
i++;
Console.WriteLine("关联token任务:" + i);
Task.Delay(500).Wait();
}
});
var key=Console.ReadKey();
if(key.Key==ConsoleKey.A)
{
cts.Cancel();
}
Console.ReadLine();