A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was
If you create a Task, and you don't ever call task.Wait()
or try to retrieve the result of a Task<T>
, when the task is collected by the garbage collector, it will tear down your application during finalization. For details, see MSDN's page on Exception Handling in the TPL.
The best option here is to "handle" the exception. This can be done via a continuation - you can attach a continuation to the task, and log/swallow/etc the exception that occurs. This provides a clean way to log task exceptions, and can be written as a simple extension method, ie:
public static void LogExceptions(this Task task)
{
task.ContinueWith( t =>
{
var aggException = t.Exception.Flatten();
foreach(var exception in aggException.InnerExceptions)
LogException(exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
With the above, you can prevent any task from tearing down the app, and logging it, via:
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
Alternatively, you can subscribe to the TaskScheduler.UnobservedTaskException and handle it there.
A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property
You're not handling any exception.
Change this line:
InsertMainLinks.Wait();
TO:
try {
InsertMainLinks.Wait();
}
catch (AggregateException ae) {
/* Do what you will */
}
In general: to prevent the finalizer from re-throwing any unhandled exceptions originating in your worker thread, you can either:
Wait on the thread and catch System.AggregateException, or just read the exception property.
EG:
Task.Factory.StartNew((s) => {
throw new Exception("ooga booga");
}, TaskCreationOptions.None).ContinueWith((Task previous) => {
var e=previous.Exception;
// Do what you will with non-null exception
});
OR
Task.Factory.StartNew((s) => {
throw new Exception("ooga booga");
}, TaskCreationOptions.None).ContinueWith((Task previous) => {
try {
previous.Wait();
}
catch (System.AggregateException ae) {
// Do what you will
}
});
A Task's exception(s) were not observed
There is probably nothing wrong. Sounds like AppInsights is being a bit paranoid.
This is most commonly caused by one of two things.
One is a "wait for any" kind of logical fork in your code. This is usually some code that uses Task.WhenAny
. I recommend searching your code for "WhenAny".
The other is a "fire and forget" kind of logic. This is usually code that calls Task.Run
and then ignores the returned task. The compiler is pretty good at warning you about fire-and-forget code (since it's almost always a mistake), so the first thing to check is your compiler warnings.
Since you have a unit test suite, you can hook up a handler for TaskScheduler.UnobservedTaskException
, which will catch these exceptions, and then run/debug your test suite and see under which tests that gets hit. If you want to quiet down AppInsights, you can add a handler in your production code that calls UnobservedTaskExceptionEventArgs.SetObserved
.
Correctly cancel task from async method when wanting to return early
I know this question is closed, but try this:
[HttpGet]
public async Task<IHttpActionResult> Test2()
{
using (var tokenSource = new CancellationTokenSource())
{
var searchTask = _productService.SearchAsync("searchterm", tokenSource.Token);
// Some sort of logic that means I want to return early, and not wait for the searchTask
int next = new Random().Next(1, 5);
if (next < 3)
{
tokenSource.Cancel();
try
{
await searchTask; // let it gracefully exit since it was cancelled.
}
catch (OperationCanceledException)
{
// swallow this
}
catch (Exception ex)
{
// log this
}
return Ok("Done");
}
var productSearchResult = await searchTask;
return Ok(productSearchResult.TotalResults);
}
}
Xamarin.Forms PopModalAsync: A Task's exception(s) were not observed
First, why are you using such a complicated syntax instead of taking advantage of async await?
public async void EndAppointement()
{
try
{
await App.ArdaBusinessLogic.AppointmentEnd(_appointment);
_appointmentDetailPage.IsDirty = true;
await App.MasterNavigationPage.Navigation.PopModalAsync();
}
catch (Exception exception)
{
await App.MasterNavigationPage.Navigation.PopModalAsync();
await App.ShowErrorPageAsync(exception);
}
}
Second, looking at XF source code:
protected override async Task<Page> OnPopModal(bool animated)
{
Page modal = ModalStack[ModalStack.Count - 1];
if (_owner.OnModalPopping(modal))
{
_owner.OnPopCanceled();
return null;
}
Page result = await base.OnPopModal(animated);
result.Parent = null;
_owner.OnModalPopped(result);
return result;
}
It seems that your modal stack is messed up: meaning you are trying to pop pages that are not on the stack. Are you sure you're on a modal page? Maybe use PopAsync
instead of PopModalAsync
.
Related Topics
How to Convert an Object to a Byte Array in C#
Linq to SQL: Multiple Joins on Multiple Columns. Is This Possible
Sending Email with Attachments from C#, Attachments Arrive as Part 1.2 in Thunderbird
C# - Code to Order by a Property Using the Property Name as a String
Best Way to Invoke Any Cross-Threaded Code
How to Represent a Time Only Value in .Net
Try/Catch + Using, Right Syntax
How to Detect If a Property Exists on an Expandoobject
Iterate Multi-Dimensional Array with Nested Foreach Statement
Grid Lines Are Not Displaying in Grid View
Executing R Script Programmatically
Why C# Implements Methods as Non-Virtual by Default
How to Get Timestamp of Tick Precision in .Net/C#
How to Use the Iequalitycomparer
An Attribute Argument Must Be a Constant Expression, ...- Create an Attribute of Type Array