4

I would like to understand how what I should be using inside of my "try" block when trying to await an Array of Tasks.

I want all tasks to be awaited, regardless if one of them threw an Exception, so that they can all complete.

Should I use:

var tasks = new Task<CasApiRouterModelExtendedInfo>[mbis.Length];

for (int i = 0; i < mbis.Length; i++)
{
    tasks[i] = CAS.Service.GetAllRouterInterfacesAsync(mbis[i], false, 2);
}

try
{
    Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
    Trace.TraceError("Some interface discoveries failed: ");
    foreach (var innerEx in ex.InnerExceptions)
    {
        Trace.TraceError(innerEx.Message);
    }
}
foreach (var task in tasks)
{
    if (task.Status == TaskStatus.RanToCompletion && task.Result != null)
    {
        returnResults.Add(task.Result);
    }
}

OR

var tasks = new Task<CasApiRouterModelExtendedInfo>[mbis.Length];

for (int i = 0; i < mbis.Length; i++)
{
    tasks[i] = Task.Run(() => CAS.Service.GetAllRouterInterfacesAsync(mbis[i], true, 2));
}

try
{
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i].Wait();
    }
}
catch (AggregateException ex)
{
    Trace.TraceError("Some interface discoveries failed: ");
    foreach (var innerEx in ex.InnerExceptions)
    {
        Trace.TraceError(innerEx.Message);
    }
}

foreach (var task in tasks)
{
    if (task.Status == TaskStatus.RanToCompletion && task.Result != null)
    {
        returnResults.Add(task.Result);
    }
}

Also, does that "task.Status == TaskStatus.RanToCompletion" return true as long as the task didn't throw an Exception (is this a good way to do this check)?

David Pine
  • 23,787
  • 10
  • 79
  • 107
blgrnboy
  • 4,877
  • 10
  • 43
  • 94

1 Answers1

2

Is there any reason you would prefer B? I can't think of one.

B is incorrect in case of error.

Also, it is bad style. Your intention is to wait for all tasks, so say that in the code. No need for manual loops obscuring what you want to accomplish.

Also, does that "task.Status == TaskStatus.RanToCompletion" return true as long as the task didn't throw an Exception (is this a good way to do this check)?

This checks for successful completion. Likely, this is what you want. Tasks can end up cancelled but likely you will consider that as an error case.

task.Result != null

Is that really what you want? task.Result is never set to null by the system. This can only happen if GetAllRouterInterfacesAsync makes the result null.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Yes, GetAllRouterInterfacesAsync() can in fact return a NULL result, so this is really what I want. What I was concerned about, is whether `Task.WaitAll(tasks)` would prevent all tasks from completing if a single task threw an Exception. Do you know if this is the case, or will all tasks complete regardless if any throw Exceptions. – blgrnboy Mar 23 '16 at 21:39
  • 1
    Nothing can prevent a task from completing. Such an API does not exist. WaitAll will also wait until all tasks are done regardless of whether an error occurs or not. None of the task combinator APIs modify a task. – usr Mar 23 '16 at 21:42