У меня есть приложение, которое проверяет с помощью ping-запросов каждый возможный IP в Вашей локальной подсети для составления списка быстро реагирующих IP-адресов. В настоящее время это проверяет с помощью ping-запросов все 255 по одному. Действительно ли возможно преобразовать это приложение для использования нескольких потоков для увеличения скорости путем проверки с помощью ping-запросов больше, чем по одному? Я плохо знаком с понятием нескольких потоков и полагаю, что это было бы хорошим способом учиться (как долго, поскольку это возможно, конечно).
также, любые стилистические улучшения, о которых можно рассказать мне, также были бы полезны.
спасибо заранее
Вот текущий метод проверки с помощью ping-запросов в backgroundWorker1_DoWork событии.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
count = 0;
for (int i = 1; i < 255; i++)
{
Ping ping = new Ping();
PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + locip[2] + "." + i));
count += 1;
if (pingreply.Status == IPStatus.Success)
{
status = "o";
repAddress = pingreply.Address.ToString(); ;
repRoundtrip = pingreply.RoundtripTime.ToString();
repTTL = pingreply.Options.Ttl.ToString();
repBuffer = pingreply.Buffer.Length.ToString();
string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
ipList.Rows.Add(lineBuffer);
}
progressBar.Invoke(new MethodInvoker(UpdateProgressBarByOne));
progressStatus.Text = ("Pinging IP " + count + " of 254");
}
button1.Enabled = true;
progressBar.Invoke(new MethodInvoker(ResetProgressBar));
}
Похоже, что пинг имеет функцию SENDASYNC . Это пост (я знаю его VB, но просто чтобы получить идею) имеет пример. Таким образом, просто измените свой отправьте на SENDASYNC и прослушать событие PingCompleted
Ну, мой совет - смотреть в ваши точки параллелизма.
Во-первых, вы получите ошибку с любым доступом к Windows Forms Objects от темы. I.e Ваш доступ к Button1 будет выбросить MDA в отладку и может быть сбой во время выполнения случайным образом. Вы должны использовать делегат и вызвать метод обратно на главный нить, используя табло.
this.Invoke(delgatetomyupdatermethod)
Во-вторых, ваше время тратится в сам пинг. Поэтому я бы порекомендовал написать список ThreadSafe (просто напишите метод с блокировкой на нем
private object locker = new object();
private void InsertIntoList(string linebuffer)
{
lock(locker)
{
ipList.Rows.Add(linebuffer);
}
}
, я бы порекомендовал использовать .NET Threampool, чтобы запустить свой метод, чтобы пинговать данный IP.
Для этого написать функцию, которая Воспользуйтесь IP To Ping и обновить список с вашим результатом, а затем позвоните в него, вправе в очередь, вспоминающие элементы в Threepool. Действительно, если вы проходите в объекте с помощью ManualResetEvent, вы даже можете написать свой код
System.Threading.WaitHandle[] waits = new System.Threading.WaitHandle[255];
//initialise the list of these and create the objects to ping.
foreach (var obj in mylistofobjectvalues)
{
System.Threading.Threadpool.QueueUserWorkItem(method, obj);
}
System.Threading.WaitHandle.WaitAll(waits);
Это метод Ping, OBJ содержит объект с помощью ManualResetEvent, и информация, который ваш метод должен пинговать ее цель.
Каждый раз, когда ваш WATHANDLE завершает, вы можете обновить свое состояние. С некоторыми важными усилиями на ваш графический интерфейс вы можете даже иметь работу асинхронно, так что ваш графический интерфейс обновляется на каждом ответе, а не только в конце.