.net CancellationToken

36 阅读1分钟

作用

需要提前终止任务,比如:请求超时、用户取消请求

案例

输入网址和打印次数,自动下载对于次数的代码,并保存到本地

改造前

image.png

static async Task<int> DownloadHtml(string url,int n)
{

    for (int i = 0; i < n; i++)
    {
        using (HttpClient client = new HttpClient())
        {
            // 定义 文件名 和 文件内容
            string filename = $@"Z:\file\file_{i+1}.txt";
            string html = await client.GetStringAsync(url);

            // 写入本地
            await File.WriteAllTextAsync(filename, html);
            await Console.Out.WriteLineAsync("写入成功");

            // 网页内容打印到控制台
            string file = await File.ReadAllTextAsync(filename);
            await Console.Out.WriteLineAsync("文件内容:" + file);
           
        }
    }
    return 0;

}

DownloadHtml("https://www.baidu.com/", 10).Wait();

改造后

超过0.5s后任务自动取消

image.png

此时只执行了两次

image.png

CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(500);
CancellationToken token = cts.Token;

DownloadHtml("https://www.baidu.com/", 10, token).Wait();

static async Task<int> DownloadHtml(string url,int n,CancellationToken  cancellationToken)
{

    for (int i = 0; i < n; i++)
    {
        using (HttpClient client = new HttpClient())
        {

            if (cancellationToken.IsCancellationRequested)
            {
                await Console.Out.WriteLineAsync("请求被取消");
                break;
            }

            // 定义 文件名 和 文件内容
            string filename = $@"Z:\file\file_{i+1}.txt";
            string html = await client.GetStringAsync(url);

            // 写入本地
            await File.WriteAllTextAsync(filename, html);
            await Console.Out.WriteLineAsync("写入成功");

            // 网页内容打印到控制台
            string file = await File.ReadAllTextAsync(filename);
            await Console.Out.WriteLineAsync("文件内容:" + file);
           
        }
    }
    return 0;

}


改进方式1

任务若提前终止,则自动抛出TaskCanceledException异常

image.png

image.png

改进方式2

image.png

image.png