G-Shadow
G-Shadow

Reputation: 188

Ping.SendAsyncCancel hangs task

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

Answers (1)

Chris Wohlert
Chris Wohlert

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

Related Questions