Reputation: 188
I'm using Ping class to ping few hosts periodically. If time for next ping comes, but previous ping was not completed yet, I call SendAsyncCancel to terminate it.
Problem appears if I disable network interface. In this case, asyncronous callback is never called and call to SendAsyncCancel never returns.
Some more info: I'm using .net 3.5 and C# VS2008 express on Windows 7 x64. I call pings from the form's Timer.Tick callback. I create Ping class only once for each host (3 hosts in total, but same with only one host). Timeout is 5 seconds. Problem is 100% repeatable.
All I found is problem with ping crash on multiple create/destroy ping classes, but it is not my case.
using System;
using System.Net.NetworkInformation;
using System.Windows.Forms;
namespace TestPing {
public partial class Form1 : Form {
private Ping Pinger;
public Form1()
{
InitializeComponent();
Pinger = new Ping();
Pinger.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
txtResult.Text = e.Cancelled ? "Cancelled" : e.Reply.Status.ToString();
}
private void butSend_Click(object sender, EventArgs e)
{
txtResult.Text = "(result)";
txtStatus.Text = "SendAsync() calling...";
Pinger.SendAsync(txtHost.Text, null);
txtStatus.Text = "SendAsync() done.";
}
private void butCancel_Click(object sender, EventArgs e)
{
txtStatus.Text = "SendAsyncCancel() calling...";
Pinger.SendAsyncCancel();
txtStatus.Text = "SendAsyncCancel() done.";
}
}
}
Upvotes: 4
Views: 556
Reputation: 600
Pinger.SendAsyncCancel(); seem to not really do this asynchronously. When using .NET 3.5 you can do the following:
private void butSend_Click(object sender, EventArgs e)
{
txtStatus.Text = "Pinging";
Pinger.SendAsync(txtHost, null);
}
private void butCancel_Click(object sender, EventArgs e)
{
Thread t = new Thread(Pinger.SendAsyncCancel);
t.Start();
}
Now, your txtStatus.Text = "Cancel done"; will go here:
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
if(e.Cancelled)
{
txtResult.Text = "Cancelled";
txtStatus.Text = "Cancel done";
}
else
{
txtResult.Text = e.Reply.Status.ToString();
txtStatus.Text = "SendAsync done";
}
}
This works like I expect it too on my end.
Upvotes: 1