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;
    }
}
相关推荐
Cheng小攸16 分钟前
CTF攻防综合实战(1)
windows
z落落36 分钟前
C# Stack栈 / Queue队列+所有集合 终极一页汇总(全覆盖、零遗漏)
java·开发语言·c#
未力忘1 小时前
【无标题】
windows
大明者省1 小时前
在 Windows Server 2019 环境下配置 IIS 站点、本地端口服务、反向代理及内外网访问、多站点多服务部署
windows
您^_^1 小时前
ClaudeCode最近更新导致第三方模型Token消耗率暴涨,缓存命中也相当夸张!!
人工智能·windows·缓存·个人开发·claudecode·deepseek v4 pro
您^_^1 小时前
新手上路(四):Codex MCP 实战——让 Codex 连接外部世界
人工智能·windows·个人开发·codex·deepseek v4 pro
开开心心就好1 小时前
小白友好的程序联网封锁实用工具
windows·eureka·计算机外设·rabbitmq·word·excel·csdn开发云
MageGojo1 小时前
小程序每日一谜怎么做:riddle 接口接入示例
windows·小程序·apache·谜语
淡海水2 小时前
08-认知篇-对比-injectfix深度解析
unity·c#·热更新·clr·hybrid·injectfix
Dfreedom.10 小时前
Windows、虚拟机、开发板组网通信原理及调试通联步骤
人工智能·windows·部署·边缘计算·开发板·模型加速