Справка по классу Ping SendAsync
Вопрос
Я новичок в программировании и не могу найти или узнать, что искать для отладки потока, запущенного методом SendAsync. Код хорошо работает с использованием метода Send, но при использовании SendAsync он переходит к waiter.WaitOne (), но я никогда не получаю обратный вызов (я думаю, так он и называется) к myPing_PingCompleted. Итак, два вопроса, как мне отладить код, когда он запускает новый поток. Я использую C # Express, поэтому он не может иметь все средства отладки, как VS. и любая идея, где я иду не так в моем коде. Благодаря
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;
using System.Net;
private void btnPingAsync_Click(object sender, EventArgs e)
{
string bIP = txtStartIP.Text;
string eIP = txtEndIP.Text;
int timeOut;
int cnt = 0;
if (eIP == null) eIP = bIP;
Ping myPing = new Ping();
PingOptions parmPing = new PingOptions();
AutoResetEvent waiter = new AutoResetEvent(false);
myPing.PingCompleted +=new PingCompletedEventHandler(myPing_PingCompleted);
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] dataBuffer = Encoding.ASCII.GetBytes(data);
if (!int.TryParse(txtTimeOut.Text, out timeOut)) timeOut = 120;
parmPing.DontFragment = true;
parmPing.Ttl = 32;
pbQueueStatus.Minimum = 0;
pbQueueStatus.Step = 10;
pbQueueStatus.Value = 0;
pbQueueStatus.Style = ProgressBarStyle.Continuous;
if (verify.ValidIPAddress(bIP) && verify.ValidIPAddress(eIP))
{
IPQueue = build.IPAddressQueue(bIP, eIP);
pbQueueStatus.Maximum = IPQueue.Count;
pbQueueStatus.TopLevelControl.UseWaitCursor= true;
pbQueueStatus.Visible = true;
while (IPQueue.Count > 0)
{
myPing.SendAsync(IPQueue.Dequeue(), timeOut, dataBuffer, parmPing, waiter);
waiter.WaitOne();
if (++cnt > 10)
{
pbQueueStatus.PerformStep();
cnt = 0;
}
}
}
}
private void myPing_PingCompleted(Object sender, PingCompletedEventArgs e)
{
PingReply reply = e.Reply;
((AutoResetEvent)e.UserState).Set();
if (reply .Status == IPStatus .Success )
{
dosomething;
}
Решение
Я предполагаю, что вы помещаете точку останова в метод myPing_PingCompleted, но в режиме отладки его просто нет. Это правильно? Р>
Код выдает какую-то ошибку? Если вы перебираете код, вызывает ли он myPing.SendAsync с правильными параметрами?
Я только что попробовал ваш код (без IPQueue, потому что это похоже на ваш пользовательский класс). Это прекрасно работает на моем конце. Я использовал один действительный IP-адрес и какой IP-адрес не существует. Это сработало хорошо в обоих случаях.
Изменить для новой информации
Хорошо, я только что попробовал это в приложении формы Windows, и это НЕ РАБОТАЕТ. Когда я попробовал это прежде, чем это было в модульном тесте. По сути, может показаться, что поток, используемый для визуализации оконной формы и обработки событий, не может быть использован для создания асинхронных запросов (возможно, потому что это поток переднего плана). Но вы можете легко обойти его, создав еще один поток для выполнения пинга. Р>
На самом деле, в идеале, именно так вы и должны это делать. Чтобы приложение формы Windows не блокировалось, когда поток занят, хорошим принципом является выполнение всей фоновой работы в отдельном потоке. Это будет держать форму окна отзывчивым. Однако будьте осторожны, при попытке доступа к элементам управления с использованием потоков фонового режима будет выдано исключение. Лучше всего прочитать все значения, которые вы хотите, в частные переменные, а затем запустить поток, который выполнит всю работу, попросит этот поток обновить другой набор переменных, а затем попросит поток forground прочитать переменные и обновить элементы управления. р>