简体   繁体   中英

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

    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.

Maybe so can tell me if it's possible to wait for all SendAsyncs to be finished before the return command be processed.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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