c#等待最后一个事件被解雇

时间:2014-04-14 20:25:03

标签: c# events wait

我尝试实现一项功能,以获得服务器列表中“最快”的服务器。 因此,我需要等到所有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完成。

我知道使用同步发送方法会更容易,但我想知道是否有解决方案,我想解决它:)

1 个答案:

答案 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;
}

我不清楚为什么你想要在第一次成功回复之外留下任何东西,如果最快就是你感兴趣的话。