Reputation: 2042
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
Upvotes: 1
Views: 2342
Reputation: 3825
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.
Upvotes: 3