C# c等待最后一个要触发的事件
我尝试实现一种功能,以获得服务器列表中最快的服务器。 因此,我需要等待,直到所有ping都通过异步方法得到处理C# c等待最后一个要触发的事件,c#,events,wait,C#,Events,Wait,我尝试实现一种功能,以获得服务器列表中最快的服务器。 因此,我需要等待,直到所有ping都通过异步方法得到处理 private List<Container.Server> serverList = new List<Container.Server>(); private Container.Server fastestServer; private IPAddress GetFastestServer(List<string> ad
private List<Container.Server> serverList = new List<Container.Server>();
private Container.Server fastestServer;
private IPAddress GetFastestServer(List<string> addresses)
{
foreach (string address in addresses)
{
Ping ping = new Ping();
ping.PingCompleted += ping_PingCompleted;
ping.SendAsync(ResolveDomainName(address), null);
}
return fastestServer.Address;
}
void ping_PingCompleted(object sender, PingCompletedEventArgs e)
{
serverList.Add(new Container.Server(e.Reply.Address, e.Reply.RoundtripTime));
fastestServer = serverList.OrderBy(o => o.Latency).FirstOrDefault();
}
处理完addressList中的所有地址后,该方法立即返回最快的地址,但不能保证所有ping都已部署
也许你可以告诉我,在处理return命令之前,是否可以等待所有sendaync完成
我知道使用synchron Send方法会更容易,但我想知道是否有一种解决方法可以解决它:我会放弃基于事件的方法,转而使用async/Wait。现在您可以:
async Task<IEnumerable<PingReply>> GetPingReplies(IEnumerable<string> hosts)
{
var tasks = hosts.Select(host => new Ping().SendPingAsync(host)).ToArray();
await Task.WhenAll(tasks);
return tasks.Select(task=>task.Result);
}
所以现在你可以从其他地方:
async Task<string> GetFastest(IEnumerable<string> hostList)
{
var replies = await GetPingReplies(hostList);
var hostsAndReplies =
hostList.Zip(replies, (host, reply) => new{host,reply});
var fastest=
hostsAndReplies
.Where(x => x.reply.Status == IPStatus.Success)
.OrderBy(x => x.reply.RoundtripTime)
.FirstOrDefault();
return fastest == null ? null : fastest.host;
}
我不清楚,如果你只对最快的回复感兴趣,那么除了第一次成功回复之外,你为什么还想留下来做任何事情。有很多方法可以做到这一点。SendAsync返回什么?您可以将其简化为返回任务。WhenAllhosts.Selecthost=>new Ping.SendPingAsynchost;甚至不需要使用async/await。@Servy:Neato!为了清晰起见,我留下了扩展版,但是是的,你是对的。虽然一行程序没有风险,但我倾向于通过调用.ToArray来确保生成热任务的查询立即具体化,因此没有重复枚举的风险。即使WhenAll在内部没有这样做,代码也不会重复序列两次。即使您希望将ToArray保留在那里,它也是多余的,因为它在内部将其转换为数组,但额外的Select,尤其是wait,会给解决方案增加一些实际的开销和复杂性。