我不确定我是否误解了Task.WhenAny的用法,但仅限于以下代码" 0"在应该打印时打印出来" 1"和" 2"然后" mx.Name"每次任务完成时:
public async void PopulateMxRecords(List<string> nsRecords, int threads)
{
ThreadPool.SetMinThreads(threads, threads);
var resolver = new DnsStubResolver();
var tasks = nsRecords.Select(ns => resolver.ResolveAsync<MxRecord>(ns, RecordType.Mx));
Console.WriteLine("0");
var finished = Task.WhenAny(tasks);
Console.WriteLine("1");
while (mxNsRecords.Count < nsRecords.Count)
{
Console.WriteLine("2");
var task = await finished;
var mxRecords = await task;
foreach(var mx in mxRecords)
Console.WriteLine(mx.Name);
}
}
DnsStubResolver是ARSoft.Tools.Net.Dns的一部分。 nsRecords列表包含多达200万个字符串。
答案 0 :(得分:0)
我不确定我是否误解了Task.WhenAny
的用法
你可能会。您似乎正在寻找的模式是interleaving。在以下示例中,请注意我所做的重要更改:
ToList()
来实现LINQ查询结果,WhenAny()
移入循环Remove(task)
,tasks.Count() > 0
运行while循环。这些是重要的变化。其他更改是让您的列表成为交错的可运行演示,其完整列表位于:https://dotnetfiddle.net/nr1gQ7
public static async Task PopulateMxRecords(List<string> nsRecords)
{
var tasks = nsRecords.Select(ns => ResolveAsync(ns)).ToList();
while (tasks.Count() > 0)
{
var task = await Task.WhenAny(tasks);
tasks.Remove(task);
var mxRecords = await task;
Console.WriteLine(mxRecords);
}
}