Информация об изменениях

Сообщение Дождаться завершения всех задач вне зависимости от исключени от 29.12.2019 4:04

Изменено 29.12.2019 4:10 Слава

Дождаться завершения всех задач вне зависимости от исключений
Здравствуйте.

Положим, у меня есть ненадёжный сервис, и я хочу получить от него некие данные. У меня есть класс:

private class CrapResult
{
    public string Crap1;
    public bool IsCrap1Received;
    public string Crap2;
    public bool IsCrap2Received;
    public string Crap3;
    public bool IsCrap3Received;
}


Я пытаюсь получить все эти значения, чтобы передать их дальше. Если получить не удаётся, я сохраняю то, что получено, и в следующий раз не запрашиваю, а наступает этот следующий раз после некоей паузы, неважно какой.

Получение делается примерно так:
var tasks = new List<Task>();
Task<string> crap1Task = null;

if (!res.IsCrap1Received)
{
    crap1Task = crapService.GetCrap1(session, id,...);
    tasks.Add(crap1Task);
}
...
await Task.WhenAll(tasks);

if (crap1Task!=null)
{
    res.IsCrap1Received = true;
    res.Crap1 = crap1Task.Result;
}
...


При этом, если хоть одна задача из списка tasks выбросит исключение, то и await Task.WhenAll(tasks) моментально прекратит работу и выбросит AggregateException, не дожидаясь, пока остальные задачи выполнятся.
забыл как программировать
Дождаться завершения всех задач вне зависимости от исключени
Здравствуйте.

Положим, у меня есть ненадёжный сервис, и я хочу получить от него некие данные. У меня есть класс:

private class CrapResult
{
    public string Crap1;
    public bool IsCrap1Received;
    public string Crap2;
    public bool IsCrap2Received;
    public string Crap3;
    public bool IsCrap3Received;
}


Я пытаюсь получить все эти значения, чтобы передать их дальше. Если получить не удаётся, я сохраняю то, что получено, и в следующий раз не запрашиваю, а наступает этот следующий раз после некоей паузы, неважно какой.

Получение делается примерно так:
var tasks = new List<Task>();
Task<string> crap1Task = null;

if (!res.IsCrap1Received)
{
    crap1Task = crapService.GetCrap1(session, id,...);
    tasks.Add(crap1Task);
}
...
await Task.WhenAll(tasks);

if (crap1Task!=null)
{
    res.IsCrap1Received = true;
    res.Crap1 = crap1Task.Result;
}
...


При этом, если хоть одна задача из списка tasks выбросит исключение, то и await Task.WhenAll(tasks) моментально прекратит работу и выбросит AggregateException, не дожидаясь, пока остальные задачи выполнятся. Но мне-то надо дождаться всех! Что мне, писать свой собственный метод, который при выбросе исключения будет убирать задачу в состоянии faulted из списка (ещё остаётся вопрос, как её найти), и ещё раз вызовет WhenAll, пока все задачи не завершатся успешно или не выбросят исключение? А неужели такой метод никто не написал до меня? Я знаю про существование метода WaitAll, но он блокирующий и мне как-то не хочется его вызывать из async-метода, или из обычного метода, который выше по стеку вызывает async-метод.

Я чувствую у себя некий пробел в знаниях, но сформулировать его не могу.
забыл как программировать