在c#中并行运行任务

时间:2018-06-19 09:49:08

标签: c# async-await task

我有下一个代码:

if(AObjList.Count > 0)
{
  var ARes = await insertA(AObjList);
  if (!ARes) return false;
}

if(BObjList.Count > 0)
{
  var BRes = await insertB(BObjList);
  if(!BRes) return false;
}

return true;

我想并行运行两个异步函数(insertA()和insertB),但如果我这样做

List<Task> tasks = new List<Task>();
if(AObjList.Count > 0)
{
  tasks.Add(insertA(AObjList));
}

if(BObjList.Count > 0)
{
  tasks.Add(insertB(BObjList));
} 

await Task.WhenAll(tasks);

我无法检查任务的结果。

有没有好方法呢?

谢谢!

编辑:问题被标记为重复,但对我而言,这不是因为在这种情况下您可以运行异步功能。所以我不能这样做:

 if(AObjList.Count > 0)
{
  var ATask = insertA(AObjList);
}

if(BObjList.Count > 0)
{
  var BTask = insertB(BObjList);
}

var ARes = await ATask; // ERROR
var BRes = await BTask  // ERROR

return true;

因为ATask和BTask变量在“if”条件范围内。

5 个答案:

答案 0 :(得分:1)

由于返回类型是布尔值,您可以这样做,并且还使用任务来附加AsyncState对象以识别任务

请阅读此处了解详情:TPL : Identify and Find Task

List<Task<bool>> tasks = new List<Task<bool>>();
//rest of the code 
if(AObjList.Count > 0)
{
  //"Task A" state object to idetify its task A
  tasks.Add(Task.Factory.StartNew(()=> insertA(AObjList), "Task A"));
}

if(BObjList.Count > 0)
{
  //"Task B" state object to idetify its task B
  tasks.Add(Task.Factory.StartNew(() => insertB(BObjList), "Task B"));
} 
await Task.WhenAll(tasks);
foreach(var t in tasks)
{
  Console.WriteLine(t.AsyncState.ToString());
  Console.WriteLine(t.Result);
}

答案 1 :(得分:1)

假设您的bool返回false并且您希望返回//need to specify the return type here List<Task<bool>> tasks = new List<Task<bool>>(); if(AObjList.Count > 0) { tasks.Add(insertA(AObjList)); } if(BObjList.Count > 0) { tasks.Add(insertB(BObjList)); } //await the result as usual await Task.WhenAll(tasks); //you can only use Result here because you've awaited. Never use this without await //as this can cause deadlocks return tasks.All(a => a.Result); ,如果其中任何一个返回false,则可以这样做:

mappedBy

答案 2 :(得分:0)

您可以将每个任务分配给单独的变量,然后使用它们来获取值,例如:

var taskA = insertA(AObjList);
var taskB = insertB(BObjList);

var tasks = new List<Task>{taskA, taskB};

await Task.WhenAll(tasks);

var resultA = await taskA;
var resultB = await taskB;

答案 3 :(得分:-2)

当然可以:

List<Task> tasks = new List<Task>();
if(AObjList.Count > 0)
{
  tasks.Add(insertA(AObjList));
}

if(BObjList.Count > 0)
{
  tasks.Add(insertB(BObjList));
} 

await Task.WhenAll(tasks);

if (tasks.Any(t => !t.Result))
{
  return false;
}

答案 4 :(得分:-2)

您可以使用并行任务。

bool aResult;
bool bResult;   

     Parallel.Invoke(() =>
                                     {
                                        if(AObjList.Count > 0)
    {
       aResult = await insertA(AObjList);

    }
                                     },  // close first Action

                                     () =>
                                     {
                                         if(BObjList.Count > 0)
    {
       bResult = await insertB(BObjList);

    }
                                     }
                                 ); //close parallel.invoke

有关详细信息,请参阅https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-use-parallel-invoke-to-execute-parallel-operations