1

無効な IP - 0.0.0.51 を渡すときに、SendAsync メソッドに問題があります。

問題は、Call back メソッド (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

単純なコンソール アプリケーションで 2 つの方法をテストしましたが、PingExceptionitsme860.0.0.51コメントしたとおりになっています。

これは何が起こっているかについての私の推測です: あなたのコメント「このメソッドが何百回も同時に呼び出されることを期待しています。」さらに、呼び出されていないということは、ワーカー スレッドでメソッドをpingSender_PingCompleted呼び出していることを意味します(例: を使用)。これが、例外のために が呼び出されない間にメイン スレッドでをキャッチできない理由です。PingStoreThreadPoolPingExceptionpingSender_PingCompleted

アップデート

あなたのコメントには、「参考までに.Net 4.0を使用しています。」と書かれています。

アプリが v3.5 以前ではなく、v4.0 を対象としていることに 100% 確信がありますか?

正確なコードを使用して問題を再現できましたが、.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);
    }
}

Framewrk 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 に答える