2016-06-14 13 views
5

Tôi đang cố gắng tìm ra lý do tại sao ứng dụng bảng điều khiển của tôi không bị rách nát bởi một ngoại lệ công việc không được giải quyết. Tất cả những gì tôi làm là tạo ra một nhiệm vụ mà ngay lập tức tôi ném một ngoại lệ. Cuối cùng tôi buộc GC. Trong ví dụ đầu tiên, tôi có một trình xử lý cho sự kiện TaskScheduler.UnobservedTaskException và tôi có thể thấy ngoại lệ được xử lý.Ứng dụng giao diện điều khiển không bị rách bởi một ngoại lệ nhiệm vụ chưa được giải quyết

static async Task ThrowsException() 
{ 
    Console.WriteLine("Throwing!"); 
    throw new Exception("Test exception"); 
} 

static void Main(string[] args) 
{ 
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 
    ThrowsException(); 
    Console.WriteLine("Collecting garbage."); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    Console.WriteLine("Done collecting garbage."); 
    Console.ReadKey(); 
} 

static void TaskScheduler_UnobservedTaskException(object sender, 
    UnobservedTaskExceptionEventArgs e) 
{ 
    Console.WriteLine("Unobserved task exception occured in finalizer."); 
    Console.WriteLine(e.Exception.InnerException.Message); 
} 

Output:

Throwing! 
Collecting garbage. 
Unobserved task exception occured in finalizer. 
Test exception 
Done collecting garbage. 

Nhưng nếu tôi nhận xét ra dòng TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException chương trình vẫn chạy đến khi kết thúc. Trong trường hợp này, đầu ra là:

Throwing! 
Collecting garbage. 
Done collecting garbage. 

Tại sao ứng dụng không gặp sự cố trong trường hợp này?

Trả lời

4

Không làm hỏng chương trình từ một ngoại lệ nhiệm vụ không được giám sát là thay đổi được thực hiện cho .NET 4.5, xem remarks section of the MSDN for the event. Nếu bạn muốn chương trình của mình có hành vi .NET 4.5 trước và khiến nó bị lỗi, bạn cần phải nhập vào app.config

<configuration> 
    <runtime> 
     <ThrowUnobservedTaskExceptions enabled="true"/> 
    </runtime> 
</configuration> 

Điều này sẽ mang lại hành vi cũ.

0

ThrowsException là một phương pháp không đồng bộ và do đó trừ khi bạn sẽ đợi phương thức này, ngoại lệ sẽ bị nuốt.
Tôi cho rằng bạn cần phải gọi phương pháp này như sau:

ThrowsException.Wait(); 

Hoặc thậm chí bắt ngoại lệ:

try 
{ 
    ThrowsException().Wait(); 
} 
catch (AggregateException e) 
{ 
    // Do something 
} 

Ngoài ra, đọc những điều sau đây sẽ giúp bạn hiểu tại sao nó không sụp đổ của bạn ứng dụng: TaskScheduler.UnobservedTaskException Event.

Các vấn đề liên quan