相关疑难解决方法(0)

Task.WhenAny取消未完成的任务并超时

在我的应用程序中,我正在创建一些并发的Web请求,并且我对其中任何一个请求完成都感到满意,因此我使用的是Task.WhenAny

var urls = new string[] {
    "https://stackoverflow.com",
    "https://superuser.com",
    "https://www.reddit.com/r/chess",
};
var tasks = urls.Select(async url =>
{
    using (var webClient = new WebClient())
    {
        return (Url: url, Data: await webClient.DownloadStringTaskAsync(url));
    }
}).ToArray();
var firstTask = await Task.WhenAny(tasks);
Console.WriteLine($"First Completed Url: {firstTask.Result.Url}");
Console.WriteLine($"Data: {firstTask.Result.Data.Length:#,0} chars");
Run Code Online (Sandbox Code Playgroud)

首次完成的网址:https
://superuser.com数据:121.954个字符

我不喜欢这种实现方式,因为未完成的任务会继续下载不再需要的数据,并且浪费带宽,我希望为下一批请求保留这些带宽。因此,我正在考虑取消其他任务,但是我不确定该怎么做。我发现了如何使用CancellationToken取消特定的Web请求:

public static async Task<(string Url, string Data)> DownloadUrl(
    string url, CancellationToken cancellationToken)
{
    try
    {
        using (var webClient = new WebClient())
        {
            cancellationToken.Register(webClient.CancelAsync);
            return (url, await webClient.DownloadStringTaskAsync(url)); …
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library async-await

8
推荐指数
1
解决办法
421
查看次数

在循环内添加一个短延迟可防止它无限循环.为什么?

在使用.NET async/await API时,我遇到了好奇心:循环忽略了用作超时的延迟,直到我在循环内添加了一个短暂的延迟.这是如何运作的?不是最直观的行为!

完整计划:

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main(String[] args)
    {
        Task.Run(async () =>
        {
            await Task.WhenAny(Loop(), Task.Delay(TimeSpan.FromSeconds(1)));
            Console.WriteLine("Timed out!");
        })
        .Wait();
    }

    public static async Task Loop()
    {
        while(true)
        {
            // Commenting this out makes the code loop indefinitely!
            await Task.Delay(TimeSpan.FromMilliseconds(1));

            // This doesn't matter.
            await DoWork();
        }
    }

    public static async Task DoWork()
    {
        await Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

背景

实际的程序有,while(!done)但由于一个错误done从未设置为true.循环进行多次await调用.该Task.WhenAny呼叫是在单元测试中以防止Loop() …

c# asynchronous task infinite-loop async-await

3
推荐指数
1
解决办法
542
查看次数