【问题标题】:.Net 2.0 Ping failing in long running system. Windows Ping succeeds.Net 2.0 Ping 在长时间运行的系统中失败。 Windows Ping 成功
【发布时间】:2011-12-14 05:07:45
【问题描述】:

我有一个用 C# 编写的 .Net 2.0 应用程序,它监视本地 LAN 上的其他 Windows XP 计算机。在某些系统上,经过较长的正常运行时间(40 到 120 天)后,.Net Ping 可能会失败。 Windows 命令提示 ping 仍然成功。

一旦发生此故障,所有 .Net Ping 似乎都会失败。使用类似代码的单独 .Net 应用程序也会失败。

以下是代码示例:

internal static bool canPingHost(string host)
{
    bool success = false;
    const int PING_TIMEOUT_MS = 1000;
    try
    {
       using (Ping p = new Ping())
       {
            PingReply pr = p.Send(host, PING_TIMEOUT_MS);
            if (pr.Status == IPStatus.Success)
            {
                success = true;
            }
        }
    }
    catch
    {                
    }
    return success;
}

本期设置要点:

  • 所有 PC 都插入同一个非托管交换机
  • 所有其他 PC 都可以使用相同的 .Net Ping 与问题系统对话。
  • Windows ping 在问题系统上正常工作。
  • 在问题系统上尝试的任何 .Net 2.0 应用程序都会失败。
  • 进出问题系统的数据库操作也可以正常工作(TCP 连接)
  • 停止和启动应用程序并不能解决问题系统上的问题。

当这个系统出现故障时,我会运行另一个应用程序并提供更多调试信息。

static string doping(IPAddress IP)
{
    int PING_TIMEOUT_MS = 3000;
    string rv = IP.ToString();

    using (Ping p = new Ping())
    {
        bool success = false;
        PingReply pr = null;
        try
        {
            pr = p.Send(IP, PING_TIMEOUT_MS);
            success = pr.Status == IPStatus.Success;
        }
        catch (Exception ex)
        {
            rv = rv +" [ " +ex.Message + " ] ";
        }

        if (pr != null)
        {
            if (success)
            {
                rv = rv + " yes " + pr.RoundtripTime.ToString();
            }
            else
            {
                rv = rv + " no " + pr.Status.ToString();
            }
        }
        else
        {
            rv = rv + " no (fail) ";
        }
    }
    return rv;
}

程序的输出是192.168.0.2 no 1450
PingReply Status 变量返回 1450,它似乎没有在 IPStatus (PingReply.Status) 枚举中定义。

重新启动问题计算机后,.Net Ping 再次开始正常工作

看起来存在某种描述的资源问题。我不确定它可能是哪个资源。

我已阅读有关异步 Ping 和 .Net 2.0 的问题。这是一个同步 ping,据我所知,它不受影响。

我正在寻找:

  • 首先预防问题
  • 建议在远程系统出现故障后对其进行调试(生产系统、Windows XP SP3、未安装开发人员工具)
  • 监控资源以确定哪个失败了。

注意事项:

  • 目前无法定期重启有问题的系统。
  • 目前不能选择升级到最新版本的 .Net Framework。
  • 将软件更改为不再使用 .Net Ping 是一种选择,但我仍然想知道发生了什么。

【问题讨论】:

  • 您可以从不只是捕获和吞下异常开始。很容易抛出一个异常,它非常清楚地解释了正在发生的事情 - 但你永远不会知道,因为你甚至没有记录就忽略了它。
  • 1450 = Windows 错误代码中的 ERROR_NO_SYSTEM_RESOURCES - 不确定这是否会进入 PingReply.Status 枚举。
  • 这听起来非常类似于 ol' Windows98 最长 48 天的正常运行时间问题。
  • @JonSkeet:失败后运行的附加应用程序确实捕获了异常。没有抛出异常,PingReply 变量正在正常返回。
  • @lnical:但是为什么不在正常流程中添加异常日志记录呢?为什么要丢失这些信息?

标签: c# .net windows-xp .net-2.0


【解决方案1】:

在同一系统上运行的另一个应用程序正在消耗大量 (> 100 MB) 池非分页字节。这发生在几个星期的时间里。

这是通过查看整个系统的性能计数器确定的。突出的是:

  • 内存,池非分页字节(覆盖整个计算机)
  • Process、_Total、Pool Nonpaged Bytes(似乎涵盖了所有正在运行的进程)
  • 系统上每个正在运行的进程的进程、池非分页字节数。

Pool Nonpaged 字节数非常大,全部集中在一个应用程序中

重新启动其他应用程序导致非分页池内存使用量返回到低得多的值。然后 Ping 成功完成。缺少非分页池内存似乎会导致 Ping 失败。

可以在页面Pushing the Limits of Windows: Paged and Nonpaged Pool 上找到有关池非分页字节的信息。当系统用完非分页字节时,可能会拒绝许多资源分配,从而导致系统极度不稳定。

非常不寻常的问题。该决议与 Ping 源没有任何直接关系。

【讨论】:

    【解决方案2】:

    您的代码看起来与我用于 ping 检查机制的代码没有太大区别。我从来没有遇到过问题,但您的问题似乎完全超出了应用程序领域。我会说要么是网卡驱动程序有问题,要么是 IP 堆栈以某种方式损坏。

        private static void Main()
        {
            using (var ping = new Ping())
            using (var waiter = new EventWaitHandle(false, EventResetMode.ManualReset))
            {
                var options = new PingOptions { DontFragment = true };
                var now = DateTime.Now;
                var data = now.ToLongDateString() + " " + now.ToLongTimeString();
                var buffer = Encoding.ASCII.GetBytes(data);
                const int Timeout = 120;
    
                ping.PingCompleted += PingCompleted;
                ping.SendAsync("www.speedtest.net", Timeout, buffer, options, waiter);
                waiter.WaitOne();
            }
    
            Console.ReadLine();
        }
    
        /// <summary>
        /// Handles the Ping Completed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Net.NetworkInformation.PingCompletedEventArgs"/> instance containing
        /// the event data.</param>
        private static void PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (e.Reply.Status == IPStatus.Success)
            {
                Console.WriteLine("Address: {0}", e.Reply.Address);
                Console.WriteLine("RoundTrip time: {0}", e.Reply.RoundtripTime);
                Console.WriteLine("Time to live: {0}", e.Reply.Options.Ttl);
                Console.WriteLine("Don't fragment: {0}", e.Reply.Options.DontFragment);
                Console.WriteLine("Buffer size: {0}", e.Reply.Buffer.Length);
                Console.WriteLine("Buffer: {0}", Encoding.ASCII.GetString(e.Reply.Buffer));
            }
            else if (e.Error != null)
            {
                Console.WriteLine(e.Error);
            }
    
            var waitHandle = e.UserState as EventWaitHandle;
    
            if (waitHandle != null)
            {
                waitHandle.Set();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2010-09-16
      • 2017-02-25
      相关资源
      最近更新 更多