How to ignore subtle exceptions with async / wait in MonoTouch?

In previous versions of MonoTouch, I used this to ignore subtle exceptions:

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

Whether this is a good discussion practice, but I would like to know to achieve the same effect using async / await keywords is now officially supported in Xamarin.iOS 6.4 .

Here is the code I use for testing:

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

When I run it, the debugger stops at AsyncVoidMethodBuilder :

enter image description here

I read that .NET 4.5 supposedly changed the behavior, so unobservable exceptions do not cause the application to crash - but this does not help if the exceptions are sent to the UIKit synchronization context where I cannot handle them.

Is there a way to ignore subtle exceptions from await in MonoTouch?

+7
c # async-await synchronizationcontext
source share
1 answer

This is the correct behavior of the async void methods: they should raise an exception in the SynchronizationContext that was active when the async void method was started.

The change mentioned in .NET 4.5 deals only with invisible task exceptions and does not apply to async void methods.

In the (Microsoft) .NET world, various SynchronizationContext implementations have different top-level error handling. WPF, WinForms, and ASP.NET have different ways of handling this error, usually as part of the Application type.

I looked at the Mono UIKit API, although I am not a regular Mono user, and could not find the top-level error handling in UIApplication , and the UIKitSynchronizationContext does not look public (or at least not documented).

Another way to look at this problem: the exception handling behavior for async void methods is designed in the same way as event handlers (see my MSDN article for more information). So you can answer the question with another question: in UIKit, how would you deal with this exception?

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

You would handle the async void exception in exactly the same way.

Alternatively, if you want to continue to use UnobservedTaskException , you may simply not observe a task exception (in async void code, Task.Run returns a task that receives an exception, and you observe it using await ):

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

However, I recommend using async void for event handlers and (ultimately) await all your tasks. This ensures that you don't get any "silent errors" (ignored task exceptions), where your program just stops working correctly and you don't know why.

+7
source share

All Articles