HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

WhenAll for .NET 3.5

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
netwhenallfor

Problem

I am trying to write a version of Task.WhenAll for .NET 3.5 using the "Task Parallel Library for .NET 3.5". This is what I came up with. Is there a better way of doing this?

public static Task WhenAll(IEnumerable tasks)
    {
        var tcs = new TaskCompletionSource();

        var remainingTasks = tasks.ToList();
        int count = remainingTasks.Count();
        var exceptions = new List();

        foreach (var task in remainingTasks)
        {
            task.ContinueWith(t =>
            {
                if (Interlocked.Decrement(ref count) == 0)
                {
                    foreach (var task1 in remainingTasks)
                    {
                        if (task1.IsFaulted)
                        {
                            exceptions.Add(task1.Exception);
                        }
                    }

                    if (exceptions.Any())
                    {
                        tcs.SetException(new AggregateException(exceptions));
                    }
                    else
                    {
                        tcs.SetResult(null);
                    }
                }
            });
        }

        return tcs.Task;
    }

Solution

int count = remainingTasks.Count();


Since remainingTasks is a List, you can use the Count property here.

var exceptions = new List();


This variable should be declared where it's used: in the if Interlocked.Decrement block.

if (task1.IsFaulted)


This means you're treating canceled tasks the same as successfully completed ones. Instead, you can check whether Exception is null.

You could also rewrite the inner foreach using LINQ:

var exceptions = remainingTasks
    .Select(task => task.Exception)
    .Where(e => e != null)
    .ToList();

Code Snippets

int count = remainingTasks.Count();
var exceptions = new List<Exception>();
if (task1.IsFaulted)
var exceptions = remainingTasks
    .Select(task => task.Exception)
    .Where(e => e != null)
    .ToList();

Context

StackExchange Code Review Q#57566, answer score: 14

Revisions (0)

No revisions yet.