簡體   English   中英

並行運行任務

[英]Running Tasks in parallel

我無法理解為什么這似乎不能並行運行任務:

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);

任務開始。 我想將所有新任務添加到列表中,然后並行執行它們。

如果GetAllRouterInterfaces是一個async方法,則結果Task已經啟動(請參閱此答案以獲取更多說明)。

這意味着tasks將包含多個任務,所有這些任務並行運行,而無需隨后調用Parallel.ForEach

您可能希望等待tasks所有條目完成,可以使用await Task.WhenAll(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);

來自評論的更新

看來,盡管GetAllRouterInterfaces處於async並返回Task但它仍在發出同步POST請求(大概在其他任何await之前)。 這可以解釋為什么在進行此請求時,每次對GetAllRouterInterfaces調用都GetAllRouterInterfaces阻塞狀態,因此您獲得的並發度最低。 理想的解決方案是發出一個異步POST請求,例如:

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

這將確保您的for循環不會被阻塞,並且請求是同時進行的。

對話后進一步更新

看來您無法使POST請求成為異步請求,並且GetAllRouterInterfaces實際上並沒有執行任何異步工作,因此,我建議以下建議:

  1. GetAllRouterInterfaces刪除async並將返回類型更改為MyReturnType
  2. 像這樣並行調用GetAllRouterInterfaces

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

我不知道我是否以正確的方式理解您。

首先,如果GetAllRouterInterfaces返回一個Task,則必須等待結果。

使用Parallel.ForEach,您無法按原樣等待任務,但是可以執行類似的操作:

public async Task RunInParallel(IEnumerable<TWhatEver> mbisItems)
{
    //mbisItems == your parameter that you want to pass to GetAllRouterInterfaces

    //degree of cucurrency
    var concurrentTasks = 3;

    //Parallel.Foreach does internally something like this:
    await Task.WhenAll(
        from partition in Partitioner.Create(mbisItems).GetPartitions(concurrentTasks)
        select Task.Run(async delegate
        {
            using (partition)
                while (partition.MoveNext())
                {
                    var currentMbis = partition.Current;
                    var yourResult = await GetAllRouterInterfaces(currentMbis,3);
                }
        }
       ));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM