Ожидание завершения всех асинхронных вызовов Ping.SendAsync - C#
Формулировка задачи:
Сканирую локальную сеть по айпишнику, и получаю список Класс сканера :
Можно отсылать синхронные запросы, но ето будет слишком медленно. В примерах MSDN использовался
IPAddress
, которые пингуются : Main функция (делегат был не обязательным) :Scanner s = new Scanner();
List<IPAddress> l = s.ScanLocal(IPAddress.Parse("10.108.1.155"), Console.WriteLine);class Scanner
{
public AutoResetEvent waiter;
public delegate void Report(string s);
List<IPAddress> result = new List<IPAddress>();
Report ReportMethod;
public Scanner()
{
this.waiter = new AutoResetEvent(false);
}
public List<IPAddress> ScanLocal(IPAddress hostAddress, Report Method)
{
ReportMethod = Method;
IPHostEntry host = Dns.GetHostEntry(hostAddress);
byte[] ip = host.AddressList[4].GetAddressBytes();
int host_ip = ip[3];
for (ip[3] = 0; ip[3] < host_ip; ip[3]++)
AddIfAlive(new IPAddress(ip));
for (ip[3] = (byte)(host_ip + 1); ip[3] != 255; ip[3]++)
AddIfAlive(new IPAddress(ip));
return result;
}
public void AddIfAlive(IPAddress address)
{
Ping pingSender = new Ping();
PingOptions packetOptions = new PingOptions(50, true);
byte[] packetData = Encoding.ASCII.GetBytes("....");
pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
pingSender.SendAsync(address, 10, packetData, packetOptions, waiter);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
PingReply reply = e.Reply;
if (reply.Status == IPStatus.Success)
{
result.Add(e.Reply.Address);
ReportMethod.Invoke(e.Reply.Address.ToString());
}
}AutoResetEvent
, но я не могу понять, где его здесь использовать. Проблема в том, что после завершенияScanLocal
некоторые вызовы еще не завершились, и продолжают изменять списокIPAddress
.Вопрос :
как мне дождаться завершения всех вызововPing.SendAsync
? Большая просьба, если кому-либо не сложно, показать возможные улучшения кода. В универе занимаемся формами и кнопкамиРешение задачи: «Ожидание завершения всех асинхронных вызовов Ping.SendAsync»
textual
Листинг программы
public async Task<string> Ping(int timeout, string ip)
{
Ping ping = new Ping();
try
{
PingReply answer = await ping.SendPingAsync(ip, timeout);
if (answer.Status == IPStatus.Success)
{
return answer.Address.ToString() + "|" + await GetMACAddress(answer.Address) + "|" + answer.RoundtripTime +
"|" + Dns.GetHostEntry(answer.Address.ToString()).HostName;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
return "";
}
public async Task<string> GetMACAddress(IPAddress ip)
{
return await Task.Run(() =>
{
byte[] macAddr = new byte[6];
uint macAddrLen = (uint)macAddr.Length;
try
{
SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
string[] sMacAddress = new string[(int)macAddrLen];
for (int i = 0; i < macAddrLen; i++)
{
sMacAddress[i] = macAddr[i].ToString("x2");
}
return string.Join(":", sMacAddress).ToUpper();
});
}