C# .Net 2.0 Ping在长时间运行的系统中失败。Windows Ping成功

C# .Net 2.0 Ping在长时间运行的系统中失败。Windows Ping成功,c#,.net,windows-xp,.net-2.0,C#,.net,Windows Xp,.net 2.0,我有一个用C#编写的.NET2.0应用程序,它监视本地局域网上的其他WindowsXP计算机。在某些系统上,在长时间正常运行(40到120天)后,.Net Ping可能会失败。Windows命令提示符ping仍然成功 一旦发生此故障,所有.Net ping都会失败。使用类似代码的单独.Net应用程序也会失败 以下是代码示例: internal static bool canPingHost(string host) { bool success = false; const in

我有一个用C#编写的.NET2.0应用程序,它监视本地局域网上的其他WindowsXP计算机。在某些系统上,在长时间正常运行(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
状态变量返回1450,该变量似乎未在
IPStatus
PingReply.Status
)枚举中定义

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

似乎存在某种描述的资源问题。我不确定它可能是哪种资源

我读过关于异步ping和.NET2.0的问题。这是一个同步ping,据我所知,它不受影响

我正在寻找:

  • 首先要预防这个问题
  • 远程系统出现故障时进行调试的建议(生产系统、Windows XP SP3、未安装开发人员工具)
  • 监视资源以确定哪个资源失败
注意事项:

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

您的代码看起来与我用于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();
        }
    }
private static void Main()
{
使用(var ping=new ping())
使用(var water=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(数据);
const int Timeout=120;
ping.PingCompleted+=PingCompleted;
ping.sendaync(“www.speedtest.net”,超时、缓冲区、选项、服务生);
服务员,等一等;
}
Console.ReadLine();
}
/// 
///处理Ping已完成事件。
/// 
///发送者。
///包含
///事件数据。
私有静态无效PingCompleted(对象发送方,PingCompletedEventArgs e)
{
if(e.Reply.Status==IPStatus.Success)
{
WriteLine(“地址:{0}”,e.Reply.Address);
WriteLine(“往返时间:{0}”,e.Reply.RoundtripTime);
WriteLine(“生存时间:{0}”,e.Reply.Options.Ttl);
WriteLine(“不分段:{0}”,e.Reply.Options.DontFragment);
WriteLine(“缓冲区大小:{0}”,e.Reply.Buffer.Length);
WriteLine(“Buffer:{0}”,Encoding.ASCII.GetString(e.Reply.Buffer));
}
否则如果(例如错误!=null)
{
控制台写入线(如错误);
}
var waitHandle=e.UserState作为EventWaitHandle;
if(waitHandle!=null)
{
waitHandle.Set();
}
}

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

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

  • 内存,池非分页字节(覆盖整个计算机)
  • 进程,总共,池非分页字节(似乎涵盖所有正在运行的进程)
  • 进程,为系统上每个正在运行的进程池非分页字节
池非分页字节是一个非常大的数字,它们都集中在一个应用程序中

重新启动另一个应用程序导致非分页池内存使用率返回到一个更低的值。Ping然后成功完成。缺少非分页池内存似乎是导致Ping失败的原因

可在页面上找到有关池非分页字节的信息。当系统耗尽非分页字节时,许多资源分配可能会被拒绝,从而导致系统极不稳定


非常不寻常的问题。解析没有与Ping源直接相关的任何内容。

您可以从捕获和接受异常开始。很容易就会抛出一个异常,非常清楚地解释发生了什么-但你永远不会知道,因为您忽略了它,甚至没有记录Windows错误代码中的.1450=ERROR\u NO\u SYSTEM\u RESOURCES-不确定这是否会进入PingReply.Status枚举。这听起来非常类似于ol'Windows98 48天的最大正常运行时间问题。@JonSkeet:失败后运行的附加应用程序确实捕获了异常。没有引发异常,PingReply变量正在retu中