2010-04-07 10 views
7

Tôi đã được đọc về Reliability Features in .NET và đã viết các lớp sau đây để khám phá ExecuteCodeWithGuaranteedCleanupKhi nào ExecuteCodeWithGuaranteedCleanup thực sự đảm bảo dọn dẹp?

class Failing 
{ 
    public void Fail() 
    { 
     RuntimeHelpers.PrepareConstrainedRegions(); 
     try 
     { 
     } 
     finally 
     { 
      RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(Code, Cleanup, "fail"); 
     } 
    } 

    private void Code(object message) 
    { 
     // Some code in here that will cause an exception... 
    } 

    private void Cleanup(object message, bool something) 
    { 
     Console.WriteLine(message); 
     Console.ReadLine(); 
    } 
} 

tôi đã thử nghiệm với một loạt các cơ quan mã cho phương pháp Code. Những điều này, và kết quả thực thi của họ được liệt kê dưới đây

Gây một OutOfMemoryException-Cleanupkhông được gọi

List<string> ss = new List<string>(); 

while (true) 
{ 
    string s = new string('x', 1000000); 

    ss.Add(s); 
} 

Gây một StackOverflowException - Cleanupkhông được gọi

Code(message); // recursive call 

Gây a ExecutionEngineException - Cleanupkhông được gọi

Environment.FailFast(message.ToString()); 

Gây một ThreadAbortException-Cleanupkhông được gọi (tuy nhiên thường xuyên try...finally cũng có thể bắt ngoại lệ này)

Thread.CurrentThread.Abort(); 

Vì vậy, câu hỏi là

  • Tôi có đang sử dụng ExecuteCodeWithGuaranteedCleanup chính xác không?
  • Khi nào là ExecuteCodeWithGuaranteedCleanup thực sự hữu ích?
+1

Chạy mã này trên máy chủ CLR triển khai ICLRPolicyManager. SQL Server. –

Trả lời

2

Một số trường hợp ngoại lệ gây tử vong cho quá trình và việc thực thi mã do người dùng cung cấp không tiếp tục. Mục đích của phương pháp ExecuteCodeWithGuaranteedCleanup là để bạn có thể đặt cấu trúc dữ liệu của mình trở lại trạng thái nhất quán. Nếu quá trình này sẽ chết dù sao cũng không có cách nào để ngăn chặn nó, điều này không có mục đích gì cả. Hệ điều hành (giả sử nó hoạt động đúng) sẽ tự động dọn sạch mọi đối tượng hạt nhân cho bạn khi quá trình kết thúc, bất kể lý do quá trình kết thúc.

Như hướng dẫn của Hans, số ICLRPolicyManager của máy chủ được phát để xác định ngoại lệ nào gây tử vong theo cách này khi mã được chạy trong một máy chủ cụ thể (đặc biệt là SQL Server). Xem lưới đẹp ở cuối trang tài liệu này: ICLRPolicyManager::SetActionOnFailure Method