많은 수의 IP 주소를 동시에 ping하기 위해이 프로그램을 작업하고 있습니다. 한 번에 하나씩 각 주소에 핑을 시도했지만 일단 50 개 이상의 호스트에 ping을 시작하면 광기가 오래갑니다. 내가 가지고있는 문제는 취소 버튼 클릭시 비동기 스레드를 중지 할 수 없어 하나 이상의 호스트를 핑 (ping) 할 때이 오류가 발생한다는 것입니다. 나는 그것을 알아낼려고 2 일을 보내고 행운이 없었다. 다음과 같이 정확한 오류는 다음과 같습니다 당신이 당신의 루프에서 모두 Ping.Send()
및 Ping.SendAsync()
를 호출하는 것을비동기 스레드가 멈추지 않습니다.
System.InvalidOperationException: An asynchronous call is already in progress. It must be completed or canceled before you can call this method. at System.Net.NetworkInformation.Ping.CheckStart(Boolean async) at System.Net.NetworkInformation.Ping.Send(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options) at MultiPing.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in f:\Dev\tfsMultiPing\Multi Ping\MultiPing\MultiPing\Form1.cs:line 139
private void pingBtn_Click(object sender, EventArgs e)
{
try
{
if (inputBox.Text == "")
{
MessageBox.Show("Please Enter an IP Address to Ping.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
else
{
MessageBox.Show("Please Cancel current Ping or wait for it to be completed");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
this.Invoke(new MethodInvoker(delegate { progressBar1.Enabled = true; }));
int i;
//Add each line in the input box to the "allLines" string array
string[] allLines = inputBox.Lines;
Ping pingSender = new Ping();
try
{
//Get an object that will block the main thread
AutoResetEvent waiter = new AutoResetEvent(false);
//When the PingCompleted even is raised,
//The PingCompletedCallback method is called.
pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
//Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
//Wait 2 seconds for a reply.
int timeout = 2000;
//Set Options for transmission:
//The data can go through 64 gateways or routers
//before it is destroyed, and the data packet
//cannot be fragmented
PingOptions options = new PingOptions(64, true);
//Check if Cancel Button was clicked
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
//Begin Loop to ping each given IP Address
for (i = 0; i < allLines.Length; i++)
{
//Check if Cancel Button was clicked
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
//Convert each line from the input box to an IP address
IPAddress address = IPAddress.Parse(allLines[i]);
//Send ping Asynchronously
//Use the waiter as the user token.
//When the callback complets, it can wake up this thread.
pingSender.SendAsync(address, timeout, buffer, options, waiter);
PingReply reply = pingSender.Send(address, timeout, buffer, options);
waiter.WaitOne();
//If a replay is recieved Print "IP Address" is up in the output box.
if (reply.Status == IPStatus.Success)
{
this.Invoke(new MethodInvoker(delegate { outputBoxLive.AppendText(address + " is up" + Environment.NewLine); }));
}
//If no reply is recieved then print "IP Address" is down in the output box.
else if (reply.Status == IPStatus.TimedOut)
{
this.Invoke(new MethodInvoker(delegate { outputBoxDown.AppendText(address + " is down" + Environment.NewLine); }));
pingSender.Dispose();
}
pingSender.Dispose();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public void pingStuff()
{
}
private static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
//If the operation was cancelled, Display a message to the user
if (e.Cancelled)
{
MessageBox.Show("Ping Cancelled");
//Let the main thread resume.
//User token is the AutoResetEvent object that the main thread is waiting for
((AutoResetEvent)e.UserState).Set();
}
//If an error occurred, Display the exception to the user.
if (e.Error != null)
{
MessageBox.Show("Ping Failed: " + e.Error.ToString());
//Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
PingReply reply = e.Reply;
DisplayReply(reply);
//Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
public static void DisplayReply(PingReply reply)
{
if (reply == null)
return;
Console.WriteLine("ping status: [0]", reply.Status);
if (reply.Status == IPStatus.Success)
{
Console.WriteLine("Address: {0}", reply.Address.ToString());
Console.WriteLine("RoundTrip time: {0}", reply.RoundtripTime);
Console.WriteLine("Time to live: {0}", reply.Options.Ttl);
Console.WriteLine("Don't fragment: {0}", reply.Options.DontFragment);
Console.WriteLine("Buffer size: {0}", reply.Buffer.Length);
}
}
public void button2_Click(object sender, EventArgs e)
{
try
{
backgroundWorker1.CancelAsync();
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
}
}
}
코드를 읽지 않고 아마도 취소 토큰을 async 메서드에 전달할 수 있습니다. – Alkasai
포럼 사이트와 달리 우리는 "감사합니다"또는 "도움을 주셨으면"또는 [그래서]에 서명하지 않습니다. "[안녕하세요, '고마워,'태그 라인 및 인사말을 게시물에서 삭제해야합니까?] (http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be 참조) -removed-from-post) –
'Invoke '를 호출하면 콜백에서'EndInvoke'를 호출해야합니다. – Mgetz