WhenAll для .NET 3.5

Я пытаюсь написать версию Task.WhenAll для .NET 3.5 с помощью «Параллельной библиотеки задач для .NET 3.5». Это то, что я придумал. Есть ли лучший способ сделать это?

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

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

        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;
    }
11 голосов | спросил Ned Stoyanov 21 J000000Monday14 2014, 15:20:04

3 ответа


14
int count = remainingTasks.Count();

Так как remainingTasks является List , вы можете использовать свойство Count.


var exceptions = new List<Exception>();

Эта переменная должна быть объявлена ​​там, где она используется: в блоке if Interlocked.Decrement.


if (task1.IsFaulted)

Это означает, что вы обрабатываете отмененные задачи так же, как успешно завершенные. Вместо этого вы можете проверить, является ли Exception null.

Вы также можете переписать внутренний foreach с помощью LINQ:

var exceptions = remainingTasks
    .Select(task => task.Exception)
    .Where(e => e != null)
    .ToList();
ответил svick 21 J000000Monday14 2014, 19:21:14
11

Мне нравится, как вы написали этот код. Всего несколько штук:

Согласованность с var

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

Почему бы не использовать var для объявления count? Мне кажется очевидным, что remainingTasks.Count() будет int, и это единственная явно типизированная переменная в вашем методе.

Нейминг

Мне не нравится task1; вы должны предпочесть здесь имя meaninfgul, например remainingTask. Также я не уверен в tcs, я мог бы назвать его completionSource.

ответил Mathieu Guindon 21 J000000Monday14 2014, 17:08:51
4

Я поклонник неудачной методологии, поэтому я бы переключил условное выражение на:

if (Interlocked.Decrement(ref count) > 0)
{
    return;
}
ответил Jesse C. Slicer 21 J000000Monday14 2014, 19:29:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132