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:
Have any kind of control over what comes through ipAddress
Complicate my code by using Regex
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:
Ping
class in method private PingReply InternalSend(...)
use native method num = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2
.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.