بينغ.سينداسينك لا تصل إلى الاتصال مرة أخرى بينغكومبليتديفينثاندلر
-
20-12-2019 - |
سؤال
أواجه بعض المشاكل مع طريقة سينداسينك عند تمرير إب غير صالح-0.0.0.51
المشكلة هي أن طريقة معاودة الاتصال (بينغسندر_بينغكومبليتد) لا حتى الحصول على استدعاء.أنا لا أرى أي أخطاء ما من أي وقت مضى.
آي بادريس.تيببريس يجد هذا إب باعتباره إب "صالح".
هنا هو رمز بلدي;واسمحوا لي أن أعرف ما أنا لا أرى هنا.
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");
}
}
}
يرجى ملاحظة أنني لا أستطيع:
لديك أي نوع من السيطرة على ما يأتي من خلال إيبادريس
تعقيد التعليمات البرمجية باستخدام التعبير العادي
المحلول
لقد اختبرت طريقتين في تطبيق وحدة تحكم بسيطة ، وأنا الحصول على PingException
ل 0.0.0.51
تماما كما ه86 علق.
هذا هو تخميني على ما يحدث:تعليقك " أتوقع أن يتم استدعاء هذه الطريقة 100 مرة في وقت واحد."زائد pingSender_PingCompleted
عدم التذرع تورط أنك استدعاء PingStore
طريقة على مؤشر ترابط عامل (على سبيل المثال.باستخدام ThreadPool
).سيكون هذا هو السبب في أنك غير قادر على التقاط PingException
على الموضوع الرئيسي الخاص بك بينما pingSender_PingCompleted
لا يتم استدعاء أبدا بسبب الاستثناء.
تحديث
في تعليقك كتبت " لمعلوماتك أنا على صافي 4.0.".
هل أنت متأكد 100%, يستهدف تطبيقك الإصدار 4.0, ليس الإصدار 3.5 أو قبل ذلك?
تمكنت من إعادة إنتاج مشكلتك باستخدام التعليمات البرمجية الخاصة بك بالضبط ، ولكن عند استهداف الإطار الصافي الإصدار 3.5 (يتم طرح استثناء الإصدار 4.0 باستخدام التعليمات البرمجية الخاصة بك).
فعلت بعض الحفر في النظام.دل لكلا الإصدارات الإطار وهذا هو ما وجدت:
- كلا الإصدارين الإطار داخل
Ping
فئة في الطريقةprivate PingReply InternalSend(...)
استخدم الطريقة الأصليةnum = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2
. - في حالة الخطأ
num
تم تعيينه على0
, ، واكتشفت أن كل إصدار إطار يتعامل مع هذا الموقف بشكل مختلف.
الإطار الإصدار 3.5 / 2.0:
if (num == 0)
{
num = Marshal.GetLastWin32Error();
if (num != 0)
{
this.FreeUnmanagedStructures();
return new PingReply((IPStatus)num);
}
}
فرامورك الإصدار 4.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);
}
كما ترى في مقتطفات الشفرة أعلاه ، في <URL> 4.0 يجب أن تكون قادرا على التقاط الاستثناء ، بينما في <URL> 3.5 يتم التعامل مع جميع أخطاء وين 32 الأصلية بصمت.