2012-09-25 26 views
25

द्वारा पकड़ा नहीं जा सकता है यह वास्तव में दिलचस्प है कि निम्न C# कोड .NET4.0 पर क्रैश हो जाएगा लेकिन .NET2.0 पर ठीक काम करेगा।क्यों AccessViolationException को .NET4.0

सी # कोड

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      ExceptionTest(); 
      Console.WriteLine("Done!"); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error !!!"); 
      Console.WriteLine(e.Message); 
     } 
    } 

    [DllImport("badapp")] 
    private static extern int ExceptionTest(); 
} 

सी ++ कोड

extern "C" __declspec(dllexport) int ExceptionTest() 
{ 
    IUnknown* pUnk = NULL; 
    pUnk->AddRef(); 
    return 0; 
} 

.NET2.0 के खिलाफ ऊपर सी # कोड संकलन, सब कुछ ठीक काम करता है तो। केवल .NET4.0 के खिलाफ इसे संकलित करने से यह रनटाइम पर क्रैश हो जाएगा।

मुझे संदेह है कि .NET4.0 के बाद सिस्टम अपवाद पकड़ तंत्र बदल दिया गया है। कोई विचार?

उत्तर

47

हां, यह .NET 4 में बदल गया है। आप उन अपवादों को नहीं पकड़ सकते जो दूषित राज्य को इंगित करते हैं। ऐसा इसलिए है क्योंकि वहां बहुत अधिक गारंटी नहीं है कि भ्रष्ट राज्य अपवाद फेंकने पर आप कुछ भी कर सकते हैं। दूषित राज्य को निष्पादित जारी रखने के लिए प्रक्रिया को वास्तव में कोई कारण नहीं है।

पुराने कोड के साथ संगतता के लिए, आप legacyCorruptedStateExceptionsPolicy तत्व को app.config में जोड़कर इस व्यवहार को बदल सकते हैं।

आप उन तरीकों को चिह्नित करके केस-दर-मामले आधार पर भी कर सकते हैं जहां आप इन अपवादों को HandleProcessCorruptedStateExceptions attribute के साथ पकड़ना चाहते हैं।

+0

ग्रेट उत्तर। बहुत बहुत धन्यवाद!!!! इस सवाल ने मुझे लंबे समय तक भ्रमित कर दिया। –

+1

मैं एक सप्ताह के लिए इस मुद्दे का पीछा कर रहा था! एक चीज जो मैं अपने दूषित राज्य के साथ उपयोगी रूप से कर सकता हूं पुनरारंभ होता है। यह एक कंसोल ऐप है जिसे * दिन में 24 घंटे चलाना चाहिए। अब यह होगा। – Andiih

+0

@Andiih जब तक दूषित बिट्स कोड नहीं है जो इसे पुनरारंभ करेगा। मैं इस उद्देश्य के लिए बाहरी निगरानी का उपयोग करूंगा। –

3
[HandleProcessCorruptedStateExceptions] 
    public static unsafe int LenghtPoint(this IntPtr point) 
    { 
     //por optimizar 
     byte* bytePoint = (byte*)point.ToPointer(); 
     byte auxByte; 
     int length = 1; 
     bool encontrado = false; 
     while (!encontrado) 
     { 

      try 
      { 

       auxByte = bytePoint[length]; 
       length++; 
      } 
      catch (System.AccessViolationException) 
      { 
       length--; 
       encontrado = true; 

      } 
     } 
     return length; 
    }