Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
GitHub or Developer Community with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
Unhandled exceptions are supposed to terminate the program. However, if you have an unhandled exception off the main thread, or in a continuation of some async task even on the main thread, the exception will be completely lost. It's not reported in the debug output, it doesn't terminate the app, it just silently fails leading to all manner of confusing behavior.
This happens on all Xamarin platforms (iOS, Android, OSX, Forms) hence my choice of Runtime as the product.
Reproduce by adding this code pretty much anywhere in the main thread of your app:
Basic thread exception:
throw new Exception("deadbeef");
throw new Exception("deadbeef");
Compare behavior with the same code added to a genuine .Net app (e.g. Windows Forms or WPF)
.Net console apps built with Xamarin Studio also lose the exception (only the basic example works; console thread is not a valid synchronization context)
On iOS, if I call InvokeOnMainThread inside the continuation instead of using TaskScheduler, the exception propagates as expected.
This is making it incredibly frustrating to test new asynchronous code. I add new things that look like they should work, set a breakpoint where I want to check my assumptions, but that breakpoint is never reached, and the app fails silently in ways I may not notice. I basically have to step through every piece of new asynchronous code I add, searching for phantoms.
Matthew, thank you for reporting this issue.
It's not clear to me whether the behavior you describe (exception is not observed on
the main thread) happens if you call any of the Wait() methods on the created task?
(Console apps running with Mono and or from the Command Prompt on Windows behave identically here: if the main thread exits before waiting the exception from the task is silently dropped.)
I believe this is, for better or worse, working as expected. .NET 4.5 changed the default so that unobserved task exceptions don't terminate the process. If you Wait () on the task, you will get the exception as expected.
More details here: http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/task-exception-handling-in-net-4-5.aspx
However, we do not support <ThrowUnobservedTaskExceptions /> at the moment, which is unfortunate as it's the config flag that gives the 'old' behavior. I will have a look at this.
I've implemented support for the config element mentioned earlier. A pull request is currently pending review: https://github.com/mono/mono/pull/2424
Hi Alexsey & Alex,
Thanks for the clarification. I do see that I was wrong about the way WPF & Windows Forms behave in this respect. It was only in debug builds where it crashed with an unhandled exception. I'm guessing MS enables the ThrowUnobservedTaskExceptions flag for debug builds much like they add bounds checking for STL containers.
I've converted all my code to use await instead of ContinueWith and haven't had any further issues.
(sorry I spelled your name wrong, Aleksey!)
That's entirely possible. I don't think that behavior is documented anywhere, though. I'll investigate at some point.
(BTW, the PR above has been merged, so you can now use this configuration element if you wish.)