我如何使用TaskFactory.StartNew <task <result>&gt;使用异步方法?

时间:2017-12-06 16:15:12

标签: c# multithreading asynchronous taskfactory

我有一个异步Func&lt;&gt;在哪里我等待&#34;对于异步方法。我想对那个Func&lt;&gt;做很多并行调用使用TaskFactory.StartNew,如下面的代码,但我收到了以下错误:

  

'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 个答案:

答案 0 :(得分:4)

假设您使用的是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().

如果您没有使用特殊任务工厂,您的代码可以简化为

test_data