【问题标题】:Ping.SendAsyncCancel hangs taskPing.SendAsyncCancel 挂起任务
【发布时间】:2016-01-27 08:55:00
【问题描述】:

我正在使用 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.";
        }
      }
    }

【问题讨论】:

  • 您能否发布相同的示例代码或将确切的代码提取到单独的测试应用程序中,以便我们进行调查?
  • 我创建了一个空项目来复制并发布它的代码。我还注意到,如果我在 ping 不存在的主机(但已连接网络)时使用 SendAsyncCancel,它只会在 ping 超时期限过去后才取消,而不是立即取消。所以问题的根源可能是在取消之前等到完成。

标签: c# ping freeze


【解决方案1】:

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 = "Cancel done";会去这里:

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

这就像我期望的那样工作。

【讨论】:

  • 谢谢,但它不能解决原来的问题。现在程序 UI 不再挂起,因为单独的线程挂起。 SendAsyncCancel 永远不会完成,Pinger 类变得不可用(操作仍然挂起)并且程序永远不会退出,因为这个线程永远等待。我想知道如果没有网络连接,奇怪的行为,为什么 ping 会永远等待。
  • 在我的测试中,在我单击取消按钮几秒钟后,文本框显示为“已取消”。这是想要的结果吧?稍后会全部发布。
  • @G-Shadow 看看你的代码是否和我的一致。
  • 我试过你的代码,但问题仍然存在。您是否尝试过拔下网线(或禁用连接)?
  • @G-Shadow,是的,插入电缆后,立即表示成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-10
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
相关资源
最近更新 更多