2013-07-25 26 views
7

Trong các phiên bản trước của MonoTouch, tôi đã sử dụng để làm điều này để bỏ qua trường hợp ngoại lệ không quan sát được:Làm thế nào để bỏ qua các ngoại lệ không được quan sát với async/await trong MonoTouch?

TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) { 
    Console.WriteLine (e); 
    e.SetObserved(); 
}; 

Cho dù đó là một thói quen tốt là gây tranh cãi nhưng tôi muốn biết để đạt được tác dụng tương tự với async/await từ khóa now officially supported in Xamarin.iOS 6.4.

Đây là mã tôi sử dụng để thử nghiệm:

async void OnClick (object sender, EventArgs e) 
{ 
    await Task.Run (() => { throw new Exception(); }); 
} 

Khi tôi chạy nó, gỡ rối dừng lại ở AsyncVoidMethodBuilder:

enter image description here

Tôi đọc mà .NET 4.5 được cho là changed the behaviour so unobserved exceptions don't crash the app -Nhưng này không giúp đỡ nếu ngoại lệ được đăng lên bối cảnh đồng bộ hóa UIKit nơi tôi không thể xử lý chúng.

Có cách nào bỏ qua các ngoại lệ không được quan sát từ await trong MonoTouch không?

+1

Bạn đề cập đến nó "tạm dừng" trong "AsyncVoidMethodBuilder'. Điều đó có nghĩa rằng nếu bạn nhấn tiếp tục ngoại lệ cuối cùng bị nuốt bởi người xử lý của bạn? Đây có phải là trường hợp chỉ trình gỡ lỗi tạm dừng ngoại lệ này không? Ngoài ra, bài viết bạn tham chiếu bao gồm một số cài đặt app.config để thực hiện công việc ngoại lệ như .NET 4. Điều đó có hữu ích không? –

+0

@Brad: Nếu tôi nhấn tiếp tục, quá trình sẽ bị treo do ngoại lệ được đưa lại trên chuỗi giao diện người dùng theo 'UIKitSynchronizationContext' cơ bản. Các thiết lập cấu hình có để làm cho hành vi * chặt chẽ hơn * vì vậy họ không nên giúp đỡ. Bạn nêu ra một điểm hợp lệ mặc dù; trong các phiên bản trước, tôi đã có thể nắm bắt các ngoại lệ trong trình xử lý không được giám sát ngay cả khi đã được ném vào chuỗi giao diện người dùng. –

+1

Có nhiều trình xử lý không được giám sát khác nhau, cho Công việc, AppDomain, v.v. Hãy thử sử dụng một trình xử lý cụ thể cho giao diện người dùng. Đang chờ trả lời các ngoại lệ trên SynchronizationContext –

Trả lời

7

Đây là hành vi đúng đắn về async void phương pháp: họ là phải để nâng cao ngoại lệ trên SynchronizationContext rằng đã hoạt động tại thời điểm phương pháp async void bắt đầu.

Thay đổi bạn đã đề cập trong .NET 4.5 chỉ xử lý với các nhiệm vụ không được đáp ứng và không áp dụng cho các phương thức async void.

Trong thế giới .NET (Microsoft), các triển khai khác nhau SynchronizationContext có cách xử lý lỗi cấp cao nhất khác nhau. WPF, WinForms và ASP.NET đều có các cách xử lý lỗi khác nhau, thường là một phần của loại Application.

Tôi đã xem qua UIKit API của Mono - mặc dù tôi không phải là người dùng Mono thông thường - và không thể tìm thấy bất kỳ lỗi xử lý lỗi cấp cao nào trong UIApplicationUIKitSynchronizationContext có vẻ như không công khai (hoặc ít nhất là tài liệu).

Một cách khác để nhìn vào vấn đề này: các hành vi xử lý ngoại lệ cho async void phương pháp được thiết kế để được giống như xử lý sự kiện sẽ có (để biết thêm, xem my MSDN article). Vì vậy, bạn có thể trả lời câu hỏi bằng một câu hỏi khác: trong UIKit, bạn xử lý ngoại lệ này như thế nào?

void OnClick (object sender, EventArgs e) 
{ 
    throw new Exception(); 
} 

Bạn có thể xử lý ngoại lệ async void của mình theo cách tương tự.

Ngoài ra, nếu bạn muốn tiếp tục sử dụng UnobservedTaskException, bạn có thể đơn giản là không quan sát ngoại trừ nhiệm vụ (trong mã async void của bạn, Task.Run trả về một nhiệm vụ mà được một ngoại lệ, và bạn đang quan sát nó bằng cách sử dụng await):

void OnClick (object sender, EventArgs e) 
{ 
    Task.Run(() => { throw new Exception(); }); 
} 

Tuy nhiên, tôi khuyên bạn nên sử dụng async void cho trình xử lý sự kiện và (cuối cùng) await trong tất cả các tác vụ của bạn. Điều này sẽ đảm bảo bạn không nhận được bất kỳ "lỗi im lặng" (ngoại lệ nhiệm vụ bị bỏ qua), nơi chương trình của bạn chỉ dừng hoạt động chính xác và bạn không biết tại sao.

+0

Cảm ơn, điều này có ý nghĩa hoàn hảo! Tôi đã không nhận ra tôi quan sát một ngoại lệ nhiệm vụ bằng cách 'chờ đợi nó. Bây giờ nếu chỉ tôi biết làm thế nào để xử lý ngoại lệ UIKit :-) –

+1

Dan, Bạn đã tìm thấy bất kỳ cách nào để quan sát các ngoại lệ UIKit? –

+1

Hi Dan, cùng một câu hỏi, bạn đã quản lý để xử lý các ngoại lệ UIKit? – Fabien

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