Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

230
Views
Using Task.WhenAll but each individual Task's success needs to be tracked

The original method is the inefficient foreach loop that awaits every job (which is an I/O bound network call):

foreach (var job in Jobs)
{
    try
    {
        await DoJobAsync(job); //Pass job to external vendor API
        job.Succeeded = true;
    }
    
    catch (Exception)
    {
        //do nothing, let loop continue
    }
}

Now to improve performance, I want to use Task.WhenAll to process all jobs in a non-blocking manner.

However, we need to make sure that each job object only has that Succeeded property set to true if the DoJobAsync task does not throw exception.

If we do this:

await Task.WhenAll(Jobs.Select(j =>
{
    var task = DoJobAsync(j);
    j.Succeeded = true;
    return task;
}));

My understanding is that if any job task ends up throwing exception, that property will still get toggled to true because each individual task is not awaited as it is created, making the code flow go right past it.

I know I can capture the Task returned by Task.WhenAll to have access to a list of all exceptions thrown, but I can't figure out a way to use them to trace back to the job that threw the exception.

How do I work around this issue?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Return the result true/false from the method DoJobAsync().

This way you can return the result directly.

await Task.WhenAll(Jobs.Select(j =>
{
    return DoJobAsync(j);
}));
over 4 years ago · Santiago Trujillo Report

0

You could use an async delegate as the selector of the Select operator:

await Task.WhenAll(Jobs.Select(async job =>
{
    await DoJobAsync(job);
    job.Succeeded = true;
}));

This way each job will be projected to a Task that will not be the original DoJobAsync(job) task, but instead a wrapper task that encapsulates the logic for updating the Succeeded property. This property will be updated immediately after the DoJobAsync(job) task completes successfully.

It is possible that multiple Job objects might have their Succeeded property updated in parallel. It depends on whether a SynchronizationContext is installed on the current thread.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!