I'm working on a network monitoring application, that pings an unknown number of hosts. I've made a class PingHost with a function zping and I called it with the help of a timer once every 2 seconds to let the 2 pings to finish, even if one of them gets TimedOut. But I think a better solution is to generate a new thread for every ping, so that the ping of every host would be independent.

Can anyone give me a hint how to do this?

namespace pinguin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void timer1_Tick(object sender, EventArgs e)
{
PingHost caca = new PingHost();
PingHost caca1 = new PingHost();
this.label1.Text = caca.zping("89.115.14.160");
this.label2.Text = caca1.zping("89.115.14.129");
}

}


    public class PingHost
{
public string zping(string dest)
{
Application.DoEvents();
Ping sender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;

string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 50;
int failed = 0;
int pingAmount = 5;
string stat = "";
{
stat = "ok";
}
else
{
stat = "not ok!";
}
return stat;
}
}
}


You can use SendAsync:

sender.PingCompleted += new PingCompletedEventHandler (PingCompletedCallback);
sender.SendAsync(dest, timeout, buffer, options, textLabel);


And the callback:

private static void PingCompletedCallback (object label, PingCompletedEventArgs e)
{
{
label.Text = "ok";
}
else
{
label.Text = "not ok!";
}
}


Disclaimer: I haven't run this code. I believe the delegate will be able to access the label, but I've had issues with it in the past.

• The callback should not update the control directly, it should use Control.Invoke() or Control.BeginInvoke() to have the UI thread do the update. Also, its "SendAsync" not "SendAsynch" :) Mar 9 '11 at 7:23
• Although it might not hurt to do a InvokeRequired check, I don't believe that would be necessary. The calling thread will be the one receiving the callback. Unless a separate thread has been spawned which is then spawning all these ping requests (unlikely), the update will already be in the UI thread.. Mar 9 '11 at 9:42
• @Mongus Pong: The documentation for SendAsync states that it uses a thread from the thread pool (msdn.microsoft.com/en-us/library/0e6kc029.aspx - under Remarks). Even if it didn't use the thread pool, the only way the event can be raised on the GUI thread is if the Ping object were able to find and somehow attach to a message loop for the creating thread, I imagine this is the sort of thing Microsoft would hi-light in the documentation if they did (they already hi-light the association between a Control and it's creating thread in the documentation) Mar 9 '11 at 11:09
• @Mongus Pong: I do however agree that InvokeRequired should be checked unless it is known for sure that you are in a different thread. Mar 9 '11 at 11:13
• @Brian: Yes you are right. I'm not quite sure what is going on - if I check InvokeRequired in the PingCompletedCallback method, I get false. However, if I register a delegate with ThreadPool.RegisterWaitForSingleObject (which is what Ping uses) and check InvokeRequired, I get true. Voodoo... Mar 9 '11 at 12:05