1

I'm having some trouble with SendAsync method when passing an invalid IP - 0.0.0.51

Problem is, the Call back method (pingSender_PingCompleted) does not even get invoked. I do not see any errors what so ever.

IPAddress.TypeParse finds this IP as a "valid" IP.

Here is my code; please let me know what I'm not seeing here.

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");
        }
    }
}

Please note that I can't:

  1. Have any kind of control over what comes through ipAddress

  2. Complicate my code by using Regex

Nandun
  • 1,802
  • 2
  • 20
  • 35
  • 1
    I would assume this is because you are using `async` like a fire and forget. Have you tried using `await pingSender.SendAsync(ipAddress,null);`? – Travis J Feb 24 '14 at 22:55
  • Thanks for the comment @TravisJ but having an await would defeat the purpose of having an async method for me. I'm expecting this method to be called 100s of times simultaneously. If things go south during SendAsync, shouldn't I see the error in the call back - e.Error ? – Nandun Feb 24 '14 at 23:02
  • Have you tried wrapping a try/catch around your `pingSender.SendAsync()` call just to make sure it's not derping out? – itsme86 Feb 24 '14 at 23:06
  • Thanks @itsme86. try catch does not work either. there are no exceptions thrown from SendAsync. – Nandun Feb 24 '14 at 23:10
  • 1
    It is probably a blocking call. Try setting a timeout if such a property exists on this 'pingSender' – Silvermind Feb 24 '14 at 23:12
  • 1
    @Nandun Well that's odd, because if I try your code with "0.0.0.51" as the ipAddress, I get an exception from the `pingSender.SendAsync()` call: An exception occurred during a Ping request. – itsme86 Feb 24 '14 at 23:15
  • @Silvermind - Thanks for the suggestion. Just tried it out and failed :( – Nandun Feb 24 '14 at 23:19
  • @itsme86 - I don't know what to say. I'm not getting any kind of an exception. FYI i'm on .Net 4.0. Don't know if that's got anything to do with it. – Nandun Feb 24 '14 at 23:24
  • Based on code above, console app will probably exit before callback can be called... – LMK Feb 23 '17 at 23:07

1 Answers1

3

I've tested your two methods in a simple console application, and I'm getting PingException for 0.0.0.51 just as itsme86 commented.

This is my guess on what is happening: your comment "I'm expecting this method to be called 100s of times simultaneously." plus pingSender_PingCompleted not being invoked implicates that you're invoking the PingStore method on a worker thread (e.g. using ThreadPool). This would be the reason why you are unable to catch the PingException on your main thread while pingSender_PingCompleted is never invoked due to the exception.

UPDATE

In your comment you wrote "FYI i'm on .Net 4.0.".

Are you 100% sure, your app targets v4.0, not v3.5 or earlier?

I was able to reproduce your problem using your exact code, but when targeting .NET Framework v3.5 (for v4.0 exception is thrown using your code).

I did some digging in System.dll for both Framework versions and this is what I found:

  • Both Framework versions inside the Ping class in method private PingReply InternalSend(...) use native method num = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2.
  • In case of error num is set to 0, and I found out that each Framework version handles this situation differently.

Framework 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);
}

As you can see in the code snippets above, in .NET v4.0 you should be able to catch the exception, while in .NET v3.5 all native WIN32 errors are handled silently.

Aoi Karasu
  • 3,730
  • 3
  • 37
  • 61
  • Thanks. I have just copied the exact code above in to a console app, and I am not seeing any kind of an Exception. there is no custom threading logic in my code. Pardon my wording in the previous comment, what i meant to say was that "I expect PingStore method to be called 100s of times. Hence I need to use SendAsync so the pinging will take place simultaneously". That being said, why I not seeing this exception that the rest of the world seems to be getting? Could it be some kind of an environment setting? – Nandun Feb 25 '14 at 17:46
  • I have updated the post with the exact code that I'm running right now. – Nandun Feb 25 '14 at 17:51
  • You are absolutely correct. I should've been more conscious about what I type. I'm on .Net 3.5. Looks like I will have to force my self in to an ugly workaround. – Nandun Feb 27 '14 at 23:42