我尝试实现一项功能,以获得服务器列表中“最快”的服务器。 因此,我需要等到所有Pings得到处理(异步方法)。
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中的所有地址后,Method立即返回最快的地址,但不保证已部署所有ping。
也许这样可以告诉我是否可以在处理返回命令之前等待所有SendAsyncs完成。
我知道使用同步发送方法会更容易,但我想知道是否有解决方案,我想解决它:)
答案 0 :(得分:2)
我抛弃基于事件的方法并切换到async / await。现在你可以:
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;
}
我不清楚为什么你想要在第一次成功回复之外留下任何东西,如果最快就是你感兴趣的话。