GetAllRouterInterfaces

GetAllRouterInterfaces

我无法理解为什么它似乎无法并行运行任务:

var tasks = new Task<MyReturnType>[mbis.Length];

for (int i = 0; i < tasks.Length; i++)
{
     tasks[i] = CAS.Service.GetAllRouterInterfaces(mbis[i], 3);
}

Parallel.ForEach(tasks, task => task.Start());


通过逐步执行,我发现这一行被评估后:

tasks[i] = CAS.Service.GetAllRouterInterfaces(mbis[i], 3);


任务开始。我想将所有新任务添加到列表中,然后并行执行它们。

最佳答案

如果GetAllRouterInterfacesasync方法,则结果Task将已经启动(有关详细说明,请参见this answer)。

这意味着tasks将包含多个任务,所有这些任务并行运行,而无需随后调用Parallel.ForEach

您可能希望等待tasks中的所有条目完成,可以使用await Task.WhenAll(tasks);进行此操作。

因此,您应该以:

var tasks = new Task<MyReturnType>[mbis.Length];

for (int i = 0; i < tasks.Length; i++)
{
    tasks[i] = CAS.Service.GetAllRouterInterfaces(mbis[i], 3);
}

await Task.WhenAll(tasks);


来自评论的更新

看来,尽管GetAllRouterInterfacesasync并返回了Task,但它仍在发出同步POST请求(大概在其他await之前)。这可以解释为什么在发出此请求时,由于每次对GetAllRouterInterfaces的调用都处于阻塞状态,所以您获得的并发性最低。理想的解决方案是发出异步POST请求,例如:

await webclient.PostAsync(request).ConfigureAwait(false);


这将确保您的for循环不会被阻塞,并且请求是同时进行的。

对话后进一步更新

看来您无法使POST请求成为异步请求,并且GetAllRouterInterfaces实际上并未执行任何异步工作,因此,我建议以下建议:


async删除GetAllRouterInterfaces并将返回类型更改为MyReturnType
像这样并行调用GetAllRouterInterfaces

var routerInterfaces = mbis.AsParallel()
    .Select(mbi => CAS.Service.GetAllRouterInterfaces(mbi, 3));

10-07 17:30