private static void PingAll(IEnumerable<System.Tuple<IPAddress, string>> hosts, Action<IEnumerable<string>> completion)
if (completion == null) throw new ArgumentNullException("completion");
if (hosts == null || !hosts.Any()) completion(Enumerable.Empty<string>());
ThreadPool.QueueUserWorkItem(delegate
var waiters = new List<ManualResetEvent>();
var onlineHosts = new List<string>();
using (var ping = new Ping())
ping.PingCompleted += (sender, args) =>
var state = (System.Tuple<string, ManualResetEvent>) args.UserState;
if (args.Reply.Status == IPStatus.Success)
lock (onlineHosts) onlineHosts.Add(state.Item1);
foreach (var host in hosts)
var mre = new ManualResetEvent(false);
var token = new System.Tuple<string, ManualResetEvent>(host.Item2, mre);
ping.SendAsync(host.Item1, 1000,new[] {(byte) 'P', (byte) 'i', (byte) 'n', (byte) 'g'}, token);
waiters.Add(new ManualResetEvent(false));
foreach (var w in waiters)
completion(Enumerable.Empty<string>());
foreach (var w in waiters)