Hãy xem xét sau đây để được chiết xuất từ một Windows 8 Metro/WinRT ứng dụng, đã được giảm đến mức tối thiểu cần thiết để hiển thị sự bất thường:Unhandled ngoại lệ xử lý không được gọi cho Metro/WinRT UI async xử lý sự kiện khoảng trống
public class App : Application
{
public App()
{
UnhandledException += (sender, e) => e.Handled = true;
}
}
public class MainPage : Page
{
private void Button_Click_1(object sender, RoutedEventArgs e)
{
throw new NotSupportedException();
}
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
throw new NotSupportedException();
}
}
Vì vậy, được cung cấp một giao diện người dùng Metro với hai nút và trình xử lý sự kiện nhấp chuột của họ, sự khác biệt duy nhất là trình xử lý sự kiện thứ hai được đánh dấu là async
.
Sau đó nhấp vào mỗi nút, tôi mong đợi trình xử lý UnhandledException sẽ được gọi trong cả hai trường hợp vì chúng (cả hai) được nhập thông qua chuỗi giao diện người dùng và ngữ cảnh đồng bộ hóa liên quan. Sự hiểu biết của tôi là, đối với phương thức async void
, bất kỳ trường hợp ngoại lệ nào cũng phải được chụp và 'bị thu hồi' (giữ nguyên ngăn xếp ban đầu) qua ngữ cảnh đồng bộ hóa ban đầu, cũng được nêu rõ trong Async/Await FAQ.
Nhưng trình xử lý UnhandledException là không phải được gọi trong trường hợp async
, do đó, ứng dụng gặp sự cố! Vì điều này thách thức những gì tôi xem xét một mô hình khác rất trực quan, tôi cần phải biết tại sao! Có, tôi biết tôi có thể quấn cơ thể của người xử lý trong một try { } catch { }
, nhưng câu hỏi của tôi là tại sao không phải là xử lý UnhandledException backstop được gọi là?
Tiếp tục nhấn mạnh tại sao điều này không có ý nghĩa, hãy xem xét các chiết xuất thực tế giống hệt nhau sau đây từ một ứng dụng WPF cũng sử dụng async/chờ đợi và nhắm mục tiêu .NET Framework 4.5:
public class App : Application
{
public App()
{
DispatcherUnhandledException += (sender, e) => e.Handled = true;
}
}
public class MainWindow : Window
{
private void Button_Click_1(object sender, RoutedEventArgs e)
{
throw new NotSupportedException();
}
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
throw new NotSupportedException();
}
}
[Có một sự khác biệt tinh tế WPF có cả trình xử lý sự kiện Application DispatcherUnhandledException cũng như trình xử lý sự kiện AppDomain UnhandledException, nhưng bạn chỉ có thể đánh dấu ngoại lệ là 'được xử lý' trong DispatcherUnhandledException, điều này phù hợp với trình xử lý sự kiện UnhandledException của Metro/WinRT ở trên.]
Sau đó nhấp vào từng mông bật, trình xử lý DispatcherUnhandledException thực sự được gọi là trong cả hai trường hợp, như mong đợi và ứng dụng không không phải là lỗi.
Bạn đã bao giờ tìm thấy cách khắc phục hay giải pháp cho điều này? Tôi đang gặp chính xác cùng một vấn đề - loại một vấn đề tê liệt với UnhandledException cho lỗi đăng nhập. –
Đừng để ngoại lệ thoát khỏi trình xử lý sự kiện 'async void'; tức là quấn cơ thể trong một khối 'try {} catch {}', hoặc truyền cơ thể như một lambda đến một hàm trợ giúp - kết thúc tốt đẹp lambda để tránh lặp lại chính bạn. –
Không phải là vấn đề với sự kiện Application.UnhandledException của Win 8.1 – foson