2012-09-25 28 views
25

Điều thực sự thú vị là mã C# sau sẽ bị lỗi trên .NET4.0 nhưng hoạt động tốt trên .NET2.0.Tại sao AccessViolationException không thể bị bắt gặp bởi .NET4.0

C# code

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

C++

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

Nếu biên dịch mã # C trên chống lại .NET2.0, mọi thứ đều hoạt động tốt. Chỉ biên dịch nó với .NET4.0 sẽ làm cho nó bị lỗi khi chạy.

Tôi nghi ngờ rằng cơ chế bắt ngoại lệ hệ thống đã được thay đổi kể từ .NET4.0. Bất kỳ ý tưởng?

Trả lời

47

Có, nó đã thay đổi trong .NET 4. Bạn không thể bắt ngoại lệ cho biết trạng thái bị hỏng. Điều này là bởi vì có khá nhiều không có đảm bảo rằng bạn có thể làm bất cứ điều gì cả khi một trường hợp ngoại lệ bị hỏng được ném. Thực tế không có lý do gì để muốn một quá trình với trạng thái bị hỏng để tiếp tục thực hiện.

Để tương thích với mã cũ hơn, bạn có thể thay đổi hành vi này bằng cách thêm phần tử legacyCorruptedStateExceptionsPolicy vào app.config.

Bạn cũng có thể làm điều đó theo từng trường hợp bằng cách đánh dấu các phương pháp mà bạn muốn nắm bắt các ngoại lệ này với HandleProcessCorruptedStateExceptions attribute.

+0

Câu trả lời hay. Cảm ơn rất nhiều!!!! Câu hỏi này làm tôi bối rối trong một thời gian dài. –

+1

Tôi đã theo đuổi vấn đề này trong một tuần! Có một điều tôi có thể làm với trạng thái hỏng của mình là khởi động lại. Một ứng dụng giao diện điều khiển của nó * nên * chạy 24 giờ mỗi ngày. Bây giờ nó sẽ. – Andiih

+0

@Andiih trừ khi các bit bị lỗi là mã sẽ khởi động lại nó. Tôi sẽ sử dụng cơ quan giám sát bên ngoài cho mục đích này. –

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; 
    } 
Các vấn đề liên quan