简体   繁体   English

C#等待最后一个事件被触发

[英]c# Wait on last event to be fired

i've tryed to implement a functionality to get the "fastest" Server of a List of Servers. 我试图实现一种功能,以获取服务器列表中“最快”的服务器。 Therefor I need to wait until all Pings got handled (Async Method). 因此,我需要等到所有Ping处理完毕(异步方法)。

    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();
    }

After all addresses in the addressList have been handled the Method immediately returns the fastest one but it's not guaranteed that all pings have been deployed. 处理完addressList中的所有地址后,该方法将立即返回最快的地址,但不能保证已部署所有ping。

Maybe so can tell me if it's possible to wait for all SendAsyncs to be finished before the return command be processed. 也许这样可以告诉我是否有可能在处理return命令之前等待所有SendAsyncs完成。

I know it'd be easier to use the synchron Send Method but I'd like to know if there's a solution the way I like to solve it :) 我知道使用同步发送方法会更容易,但是我想知道是否有一种我喜欢的解决方法:)

I'd ditch the event based method and switch to async/await. 我放弃了基于事件的方法,并切换到异步/等待。 Now you can: 现在你可以:

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);

}

so now from elsewhere you could perhaps: 所以现在从其他地方可能您可以:

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

It's not clear to me why you want to hang around for anything beyond the first successful reply though, if the fastest is all that you are interested in. 对我来说,不清楚的是,如果最快的就是您感兴趣的,那么为什么除了第一笔成功的答复之外,您还想闲逛。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM