locked
A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property RRS feed

  • Question

  • User-1734903599 posted

    <div class="body"> <div>

    In Asp.net 4.0, mvc 4, i am using Task.

    My reference Code::

    List<Task> lstTask = new List<Task>();
    lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method1()));
    lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method2()));
    lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method3()));
    
     try 
    {
      Task.WaitAll(lstTask.ToArray(), 2000);
    }
     
    catch(AggregateException)
    {
    //just catch not to do anything
     }
    
     catch(Exception) {
    //just catch not to do anything
     }

    Now Method1, Method2, Method3 wil do web request. After Wait All , I will Loop through all the task and will get resutl from each task. Below is my reference code

    foreach (var tsk in lstTask) 
    {
    if (tsk.IsCompleted)
     
    {
    // Some other stuff
     
    }
    }

    Method1/2/3 has below code:

    public CustomClass Method1/2/3() 
    {
    try
    {

    // Do Web request
    // Do other process
    return CustomClass;
    }
     catch(exception ex)
    {
     throw;
     }
     }

    Now i was getting below error, "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 rethrown by the finalizer thread."

    it seems cause of this error is, main thread waits for 2 seconds. After its wait timeout, and main thread continues its execution.

    But if Tasks (Method1/2/3) not yet completed, and continue their processing. If any Exception occurred in any task then it will directly throws that exception.

    Now because main thread is not waiting (timeout) and could not catch that exception, so nobody catch this exception might cause this issue.

    So as a solution , I used CancelToken. After wait timeout cancel the token. And in all tasks (Method1/2/3), before throw exception, will check if token has been canceled then not throw exception, otherwise throw it.

    var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token;

    List<Task> lstTask = new List<Task>(); 
    lstTask
    .Add(Task<CustomClass>.Factory.StartNew(() => Method1(token)));
     lstTask
    .Add(Task<CustomClass>.Factory.StartNew(() => Method2(token)));
     lstTask
    .Add(Task<CustomClass>.Factory.StartNew(() => Method3(token)));

     
    try
    {
    Task.WaitAll(lstTask.ToArray(), 2000, token);
      tokenSource.Cancel();
    }
     
    catch(AggregateException)
    {
    //just catch not to do anything

    }
     
    catch(Exception)
     
    {
    //just catch not to do anything

     
    }

    public CustomClass Method1/2/3()
    {
    try
    {
     
    // Do Web request
    // Do process
    return CustomClass;
     
    }
    catch(exception ex)
     
    {
    if (!token.IsCancellationRequested)
    { throw; }
    }

    return
    new CustomClass();
    }
     

    So is this proper solution?

    Monday, July 1, 2013 8:40 AM

Answers

  • User1779161005 posted

    You need to access the Result (or Exception if the Task IsFaulted) properties to have the Task think it's been observed. So I'd do this in the AggregateException catch block.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 1, 2013 10:51 AM