windows C#-取消任务列表(下)

创建异步总和页面大小方法

在 Main 方法下,添加 SumPageSizesAsync 方法:

复制代码
static async Task SumPageSizesAsync()
{
    var stopwatch = Stopwatch.StartNew();

    int total = 0;
    foreach (string url in s_urlList)
    {
        int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
        total += contentLength;
    }

    stopwatch.Stop();

    Console.WriteLine($"\nTotal bytes returned:  {total:#,#}");
    Console.WriteLine($"Elapsed time:          {stopwatch.Elapsed}\n");
}

该方法从实例化和启动 Stopwatch 开始。 然后会在 s_urlList 的每个 URL 中进行循环,并调用 ProcessUrlAsync。 对于每次迭代,s_cts.Token 都会传递到 ProcessUrlAsync 方法中,并且代码将返回 Task<TResult>,其中 TResult 是一个整数:

复制代码
int total = 0;
foreach (string url in s_urlList)
{
    int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
    total += contentLength;
}
添加进程方法

在 SumPageSizesAsync 方法下添加以下 ProcessUrlAsync 方法:

复制代码
static async Task<int> ProcessUrlAsync(string url, HttpClient client, CancellationToken token)
{
    HttpResponseMessage response = await client.GetAsync(url, token);
    byte[] content = await response.Content.ReadAsByteArrayAsync(token);
    Console.WriteLine($"{url,-60} {content.Length,10:#,#}");

    return content.Length;
}

对于任何给定的 URL,该方法都将使用提供的 client 实例以 byte[] 形式来获取响应。 CancellationToken 实例会传递到 HttpClient.GetAsync(String, CancellationToken) 和 HttpContent.ReadAsByteArrayAsync() 方法中。 token 用于注册请求取消。 将 URL 和长度写入控制台后会返回该长度。

示例应用程序输出
复制代码
Application started.
Press the ENTER key to cancel...

https://learn.microsoft.com                                       37,357
https://learn.microsoft.com/aspnet/core                           85,589
https://learn.microsoft.com/azure                                398,939
https://learn.microsoft.com/azure/devops                          73,663
https://learn.microsoft.com/dotnet                                67,452
https://learn.microsoft.com/dynamics365                           48,582
https://learn.microsoft.com/education                             22,924

ENTER key pressed: cancelling downloads.

Application ending.
完整示例

下列代码是示例的 Program.cs 文件的完整文本:

复制代码
using System.Diagnostics;

class Program
{
    static readonly CancellationTokenSource s_cts = new CancellationTokenSource();

    static readonly HttpClient s_client = new HttpClient
    {
        MaxResponseContentBufferSize = 1_000_000
    };

    static readonly IEnumerable<string> s_urlList = new string[]
    {
            "https://learn.microsoft.com",
            "https://learn.microsoft.com/aspnet/core",
            "https://learn.microsoft.com/azure",
            "https://learn.microsoft.com/azure/devops",
            "https://learn.microsoft.com/dotnet",
            "https://learn.microsoft.com/dynamics365",
            "https://learn.microsoft.com/education",
            "https://learn.microsoft.com/enterprise-mobility-security",
            "https://learn.microsoft.com/gaming",
            "https://learn.microsoft.com/graph",
            "https://learn.microsoft.com/microsoft-365",
            "https://learn.microsoft.com/office",
            "https://learn.microsoft.com/powershell",
            "https://learn.microsoft.com/sql",
            "https://learn.microsoft.com/surface",
            "https://learn.microsoft.com/system-center",
            "https://learn.microsoft.com/visualstudio",
            "https://learn.microsoft.com/windows",
            "https://learn.microsoft.com/maui"
    };

    static async Task Main()
    {
        Console.WriteLine("Application started.");
        Console.WriteLine("Press the ENTER key to cancel...\n");

        Task cancelTask = Task.Run(() =>
        {
            while (Console.ReadKey().Key != ConsoleKey.Enter)
            {
                Console.WriteLine("Press the ENTER key to cancel...");
            }

            Console.WriteLine("\nENTER key pressed: cancelling downloads.\n");
            s_cts.Cancel();
        });

        Task sumPageSizesTask = SumPageSizesAsync();

        Task finishedTask = await Task.WhenAny(new[] { cancelTask, sumPageSizesTask });
        if (finishedTask == cancelTask)
        {
            // wait for the cancellation to take place:
            try
            {
                await sumPageSizesTask;
                Console.WriteLine("Download task completed before cancel request was processed.");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Download task has been cancelled.");
            }
        }

        Console.WriteLine("Application ending.");
    }

    static async Task SumPageSizesAsync()
    {
        var stopwatch = Stopwatch.StartNew();

        int total = 0;
        foreach (string url in s_urlList)
        {
            int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
            total += contentLength;
        }

        stopwatch.Stop();

        Console.WriteLine($"\nTotal bytes returned:  {total:#,#}");
        Console.WriteLine($"Elapsed time:          {stopwatch.Elapsed}\n");
    }

    static async Task<int> ProcessUrlAsync(string url, HttpClient client, CancellationToken token)
    {
        HttpResponseMessage response = await client.GetAsync(url, token);
        byte[] content = await response.Content.ReadAsByteArrayAsync(token);
        Console.WriteLine($"{url,-60} {content.Length,10:#,#}");

        return content.Length;
    }
}
相关推荐
mudtools44 分钟前
.NET驾驭Word之力:玩转文本与格式
c#·.net
唐青枫4 小时前
C#.NET 数据库开发提速秘籍:SqlSugar 实战详解
c#·.net
mudtools20 小时前
.NET驾驭Word之力:理解Word对象模型核心 (Application, Document, Range)
c#·.net
大飞pkz1 天前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式
唐青枫1 天前
从入门到进阶:C#.NET Stopwatch 计时与性能测量全攻略
c#·.net
路由侠内网穿透1 天前
本地部署 GPS 跟踪系统 Traccar 并实现外部访问
运维·服务器·网络·windows·tcp/ip
研华嵌入式2 天前
如何在高通跃龙QCS6490 Arm架构上使用Windows 11 IoT企业版?
arm开发·windows·嵌入式硬件
未来之窗软件服务2 天前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
1uther2 天前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
阿幸软件杂货间2 天前
Office转PDF转换器v1.0.py
开发语言·pdf·c#