Как я могу использовать TaskFactory.StartNew<Task <Result >> с асинхронными методами?

У меня есть асинхронный Func<>, где я "жду" для асинхронного метода. Я хочу сделать много параллельных вызовов этому Func <>, используя TaskFactory.StartNew, как и в приведенном ниже коде, но я получаю ошибку followin:

ошибка преобразования 'System.Threading.Tasks.Task<System.Threading.Tasks.Task<Result>>' в 'System.Threading.Tasks.Task<Result>'

Как я могу иметь параллельные вызовы для асинхронного метода?

Func<object, Task<Result>> action = async (object m) =>
{
    try
    {
        return await Send<Message, Result>(m as Message);
    }
    catch (Exception exc)
    {
        Result result = new Result();
        (result as ResponseBaseDto).Success = false;
        (result as ResponseBaseDto).ErrorList = new List<Entities.Common.ErrorDto>()
        {
            new Entities.Common.ErrorDto{ Code = 9999, Message = exc.Message }
        };
        return result;
    }
};

// Error on request.ForEach
request.ForEach(r => sending.Add(taskFactory.StartNew<Task<Result>>(action, r)));
var tareas = sending.ToArray();
await Task.WhenAll(tareas);
return tareas.Select(s => s.Result).ToList();

1 ответ

Решение

Предполагая, что вы используете taskFactory.StartNew( вместо Task.Run( потому что у вас есть специальный настроенный TaskFactory вам нужно использовать простое решение, это использовать .Unwrap() метод расширения, чтобы развернуть вложенную задачу.

Вы также должны заменить .ForEach(r=> sending.Add( с .Select(r => заявление, чтобы уменьшить количество итераций списка. Если вы возвращаете IEnumerable<Result> вместо List<Result> Вы можете удалить свой финал .ToList() тоже.

var tareas = request.Select(r => taskFactory.StartNew<Task<Result>>(action, r).Unwrap());
var results = await Task.WhenAll(tareas); //results is a `Result[]`
return results.ToList(); // you may not need this .ToList().

Если вы не используете специальную фабрику задач, ваш код может быть упрощен до

var tareas = request.Select(r => Task.Run(() => action(r)));
var results = await Task.WhenAll(tareas); //results is a `Result[]`
return results.ToList(); // you may not need this .ToList().
Другие вопросы по тегам