Ping.SendAsync не выполняет обратный вызов PingCompletedEventHandler

StackOverflow https://stackoverflow.com//questions/22000843

Вопрос

У меня возникли некоторые проблемы с методом SendAsync при передаче недопустимого IP-адреса - 0.0.0.51

Проблема в том, что метод обратного вызова (pingSender_PingCompleted) даже не вызывается.Я не вижу никаких ошибок, каких бы то ни было.

IP-адрес.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. Усложните мой код, используя регулярное выражение

Это было полезно?

Решение

Я протестировал ваши два метода в простом консольном приложении, и я получаю PingException для 0.0.0.51 точно так же , как itsme86 прокомментировал.

Это мое предположение о том, что происходит:ваш комментарий "Я ожидаю, что этот метод будет вызываться 100 раз одновременно". плюс pingSender_PingCompleted отсутствие вызова подразумевает, что вы вызываете PingStore метод в рабочем потоке (например,используя ThreadPool).Это было бы причиной, по которой вы не можете поймать PingException в вашем основном потоке, пока pingSender_PingCompleted никогда не вызывается из-за исключения.

Обновить

В своем комментарии вы написали "К вашему сведению, я работаю на .Net 4.0"..

Вы на 100% уверены, что ваше приложение нацелено на версию 4.0, а не на версию 5 или более раннюю?

Я смог воспроизвести вашу проблему, используя ваш точный код, но при таргетинге на .NET Framework версии v3.5 (для версии 4.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 версии 4.0 вы должны быть в состоянии перехватить исключение, в то время как в .NET версии 5 все собственные ошибки WIN32 обрабатываются автоматически.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top