1

传递无效 IP - 0.0.0.51 时,我在使用 SendAsync 方法时遇到问题

问题是,回调方法(pingSender_PingCompleted)甚至没有被调用。我没有看到任何错误。

IPAddress.TypeParse 将此 IP 视为“有效”IP。

这是我的代码;请让我知道我在这里没有看到什么。

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program c = new Program();

            try
            {
                c.PingStore("0.0.0.51");
                Console.WriteLine("Pinged without exceptions");
            }
            catch (Exception ex) 
            {
                Console.WriteLine(ex.Message);
            }
        }

        private void PingStore(string ipAddress)
        {
            Ping pingSender = new Ping();

            pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_PingCompleted);

            pingSender.SendAsync(ipAddress, null);
        }

        private void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            Console.WriteLine("PingCompleted invoked. continue to be happy");
        }
    }
}

请注意,我不能:

  1. 对来自 ipAddress 的内容进行任何形式的控制

  2. 使用正则表达式使我的代码复杂化

4

1 回答 1

3

我已经在一个简单的控制台应用程序中测试了您的两种方法,并且正如itsme86 所PingException评论的那样。0.0.0.51

这是我对正在发生的事情的猜测:您的评论“我希望这种方法同时被调用 100 次。” 加上pingSender_PingCompleted没有被调用暗示你正在调用PingStore工作线程上的方法(例如 using ThreadPool)。这就是为什么您无法PingException在主线程上捕获,而pingSender_PingCompleted由于异常而从未被调用的原因。

更新

在您的评论中,您写道“仅供参考,我在 .Net 4.0 上。”。

您是否 100% 确定您的应用针对的是 v4.0,而不是 v3.5 或更早版本?

我能够使用您的确切代码重现您的问题,但是在针对 .NET Framework v3.5 时(使用您的代码引发 v4.0 异常)。

我对两个框架版本的 System.dll 进行了一些挖掘,这就是我发现的:

  • Ping方法中的类中的两个框架版本都private PingReply InternalSend(...)使用本地方法num = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2
  • 如果错误num设置为0,我发现每个框架版本处理这种情况的方式不同。

框架 v3.5/2.0:

if (num == 0)
{
    num = Marshal.GetLastWin32Error();
    if (num != 0)
    {
        this.FreeUnmanagedStructures();
        return new PingReply((IPStatus)num);
    }
}

框架 v4.0/4.5:

if (num == 0)
{
    num = Marshal.GetLastWin32Error();
    if (async && (long)num == 997L)
    {
        return null;
    }
    this.FreeUnmanagedStructures();
    this.UnregisterWaitHandle();
    if (async || num < 11002 || num > 11045)
    {
        /* NOTE! This throws the exception for 0.0.0.51 address that you're not getting */
        throw new Win32Exception(num);
    }
    return new PingReply((IPStatus)num);
}

正如您在上面的代码片段中看到的,在 .NET v4.0 中,您应该能够捕获异常,而在 .NET v3.5 中,所有本机 WIN32 错误都被静默处理。

于 2014-02-25T01:15:09.627 回答