You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Task.WhenAny用法疑问:代码未按预期输出的技术咨询

嘿,我来帮你捋清楚Task.WhenAny的问题~你现在的代码只打印了"0",主要是两个核心原因:一是没循环处理所有完成的任务,二是缺少任务执行阶段的打印逻辑,咱们一步步来修正。

首先拆解你原代码的问题:Task.WhenAny只会返回第一个完成的任务,如果只调用一次,处理完这个任务后剩下的任务根本没被处理,程序可能直接结束,所以看不到后续输出;另外你预期的"1""2",当前代码里完全没加这部分打印逻辑,自然不会输出。

给你改好的代码,关键修正点都标在注释里了:

public async Task PopulateMxRecords(List<string> nsRecords, int threads) 
{ 
    ThreadPool.SetMinThreads(threads, threads); 
    var resolver = new DnsStubResolver(); 

    // 1. 用async lambda包装任务,添加启动时的打印(对应你要的"1""2")
    var tasks = nsRecords.Select(async ns => 
    {
        // 如果你的nsRecords刚好是两个元素,也可以直接写Console.WriteLine("1")/Console.WriteLine("2")
        Console.WriteLine($"{ns} 启动执行(对应预期序号)"); 
        var mxRecords = await resolver.ResolveAsync<MxRecord>(ns, RecordType.Mx);
        return (Ns: ns, MxRecords: mxRecords);
    }).ToList(); 

    Console.WriteLine("0"); 

    // 2. 循环处理所有任务,直到没有未完成的任务
    while (tasks.Count > 0)
    {
        var finishedTask = await Task.WhenAny(tasks);
        tasks.Remove(finishedTask); // 移除已完成的任务,避免重复处理

        try
        {
            var result = await finishedTask; 
            // 3. 任务完成后打印每个MX记录的Name
            foreach (var mx in result.MxRecords)
            {
                Console.WriteLine(mx.Name);
            }
        }
        catch (Exception ex)
        {
            // 别忘了处理任务可能抛出的异常
            Console.WriteLine($"处理域名{result.Ns}时出错:{ex.Message}");
        }
    }
}

再给你划几个必须注意的点:

  • 把async void改成async Task:async void一般只用于事件处理场景,改成async Task后调用方可以await这个方法,避免程序在任务还没跑完就提前退出。
  • 循环+移除已完成任务:这是用Task.WhenAny处理多任务的标准写法,能确保每个完成的任务都会被处理到。
  • 包装任务添加打印:在每个任务启动时加入你要的"1""2"输出,这样就能符合你预期的输出顺序。

这样改完后,程序会先打印"0",然后每个任务启动时打印对应的标识(比如"1""2"),之后每当有任务完成,就会输出该任务拿到的所有mx.Name啦~

内容的提问来源于stack exchange,提问作者user3713080

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:16:30