Ping.SendAsyncCancel挂起任务

时间:2016-01-27 08:55:00

标签: c# ping hang

我正在使用Ping类定期ping几台主机。如果下一次ping的时间到了,但之前的ping还没有完成,我调用SendAsyncCancel来终止它。

如果禁用网络接口,则会出现问题。在这种情况下,永远不会调用异步回调,并且永远不会返回对SendAsyncCancel的调用。

更多信息:我在Windows 7 x64上使用.net 3.5和C#VS2008 express。我从表单的Timer.Tick回调中调用ping。我为每个主机只创建一次Ping类(总共3个主机,但只有一个主机相同)。超时是5秒。问题是100%可重复的。

我发现所有在多个创建/销毁ping类的ping崩溃问题,但不是我的情况。

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.";
        }
      }
    }

1 个答案:

答案 0 :(得分:0)

Pinger.SendAsyncCancel();似乎不是真的异步这样做。使用.NET 3.5时,您可以执行以下操作:

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();
}

现在,你的txtStatus.Text =“取消完成”;会去这里:

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";
  }
}

这就像我期望的那样。