none
Exception Info: System.AggregateException at System.Threading.Tasks.TaskExceptionHolder.Finalize()

    Question

  • Dear all,

    I have a an application which use Task.Factory.StartNew() for long operation process or call to Database service. Time to time in my application I get big crash without event playing with the interface.

    By checking on event log I find out such error :

    Exception Info: System.AggregateException

    Stack:

       at System.Threading.Tasks.TaskExceptionHolder.Finalize()

    I guess it is somewhow related to a particular Task which gets and exception while running and not trapped correctly but not even sure :

    The way I am using tasks is as follow :

    Task.Factory.StartNew(()=>ViewModelLocator.CreateMapViewModelStatic());
    Or this way :

     Task.Factory.StartNew(() =>
                    {
                        //Remove the polygone on the map associated to the tagvizualizer
                        var c = (from poly in ViewModelLocator.WorldMapViewModelStatic.PolygonsCollection
                                 where poly.TagVisualizerOwner.VisualizedTag.Value == _tagv.VisualizedTag.Value
                                 select poly).ToList();
    
                        foreach (var item in c)
                        {
                            ViewModelLocator.WorldMapViewModelStatic.PolygonsCollection.Remove(item);
                        }
                    }, CancellationToken.None, TaskCreationOptions.None, AppState.Instance.EnvironnementState.UiScheduler);

    Or also that way width .COntiNueWith:

    Task.Factory.StartNew(() =>
                                                                       {
                                                                           this.GetCustomerBasketInformation(this.Customer.Name, this.Customer.Email, ViewModelLocator.WorldMapViewModelStatic.Realtor);
                                                                       }).ContinueWith(task =>
                                                                       {
                                                                           Messenger.Default.Send(new PropertyAgent.Message.BringSearchResultPanelToView(this));
                                                                       },CancellationToken.None,TaskContinuationOptions.None,AppState.Instance.EnvironnementState.UiScheduler);

    I have a try catch at the beggingin of the method but seems it is not catching properly.

    How and where can I set proper try catch in my Task.Factory.StartNew() in order to log properly potential error that could occurs in parallel running task ?

    Actually, It simply crash my whole application.

    thnaks for your help

     

    Your knowledge is enhanced by that of others.

    Tuesday, January 15, 2013 5:31 PM

Answers

All replies

  • What's happening is that your task throws an exception, and you never catch it.

    If you write this:

    try
    {
        Task.Factory.StartNew( () =>
        {
            // Simulate some work
            Thread.Sleep(1000); 
            throw new Exception("Bad thing happened");
        });
    catch (Exception e)
    {
       // This won't catch it!
    }

    You'll see that you never catch the exception, since it's happening in a background thread, and not your main thread.  In order to catch the AggregateException from a Task, you need to either call Task.Wait() or Task<T>.Result on the task, which raises the internal exception.

    You can add a continuation and call Task.Wait() or Task.Result within a try/catch, which will catch (and handle) the exception.  This will prevent the unhandled exception from happening, and tearing down your application.

    A last resort is also to subscribe to TaskScheduler.UnobservedTaskException, which allows you to log or handle the exception before it tears down your application.

    For details, see the Exception Handling doc for the TPL on MSDN: http://msdn.microsoft.com/en-us/library/dd997415.aspx


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Tuesday, January 15, 2013 6:41 PM
  • In .Net 4.0, when an exception inside a Task is unobserved, it crashes the application when that Task is garbage collected. What you should do is to figure out what caused that exception (by looking at the InnerException of the AggregateException) and fix that.

    If, for some reason, you can't or don't want to do that, you have to observe the exception somehow. There are several options:

    1. Wait for the Task synchronously by calling Wait(). For faulted Task, this will throw the exception.
    2. Wait for the Task asynchronously by using ContinueWith(). In the callback, access the Exception property.
    3. Subscribe to TaskScheduler.UnobservedTaskException and call SetObserved() on the event args.
    Tuesday, January 15, 2013 6:47 PM
  • Thanks for your reply.

    But where and how should I place the try/cathch whne my task is using the .ContinueWith as follow to update some UI or other stuff :

    Task.Factory.StartNew(() => { DoSomeWork(); }).ContinueWith(task => {

    UpdateUIMessage();

    },CancellationToken.None,TaskContinuationOptions.None,AppState.Instance.EnvironnementState.UiScheduler);

    IN my scenario above  I wan to call the UpdateUiMessage() only if DoSomeWork is complete BUT I would like also to log any exception that occurs in the Task process.

    I do not see how should I place the try/catch ?

    Thnaks for your sample

    regards

    serge


    Your knowledge is enhanced by that of others.



    Wednesday, January 16, 2013 7:57 AM
  • One way would be to check whether the Task is faulted in the continuation:

    ContinueWith(task => {
        if (task.IsFaulted)
            LogException(task.Exception);
        else
            UpdateUIMessage();
    }, …)
    Wednesday, January 16, 2013 1:26 PM
  • thnaks will give a try

    Your knowledge is enhanced by that of others.

    Wednesday, January 16, 2013 3:16 PM