簡體   English   中英

使用異步/等待任務繼續並行執行

[英]Task continuation parallel execution with async/await

在使用async / await構造的控制台應用程序的上下文中,我想知道“繼續”是否有可能在不同CPU上的多個線程上並行運行。

我認為是這種情況,因為繼續發布在默認任務計划程序(控制台應用程序中沒有SynchronizationContext)上,即線程池。

我知道async / await構造不會構造任何其他線程。 仍然應該由線程池為每個CPU構造至少一個線程,因此,如果在線程池上發布了延續,它可以在不同CPU上並行調度任務繼續...這就是我的想法,但是由於某種原因,我昨天對此感到非常困惑,我現在不確定。

這是一些簡單的代碼:

public class AsyncTest
{
  int i;

  public async Task DoOpAsync()
  {
    await SomeOperationAsync();

    // Does the following code continuation can run 
    // in parrallel ?
    i++;       

    // some other continuation code ....
  }

  public void Start()
  {
    for (int i=0; i<1000; i++)
    { var _ = DoOpAsync(); } // dummy variable to bypass warning
  }
}

SomeOperationAsync本身不會創建任何線程,而為示例起見,它只是依靠I / O完成端口異步發送一些請求,因此根本不會阻塞任何線程。

現在,如果我調用將發出1000次異步操作的Start方法,異步方法的繼續代碼(在等待之后)是否可以在不同的CPU線程上並行運行? 也就是說,在這種情況下,我是否需要注意線程同步並同步對字段“ i”的訪問?

是的,您應該將線程同步邏輯放在i++因為有可能多個線程將在await之后同時執行代碼。

由於for循環,將創建許多任務。 這些任務將在不同的線程池線程上執行。 這些任務完成后,繼續(即等待后的代碼)將在不同的線程池線程上再次執行。 這使得多個線程可以同時執行i ++

您的理解是正確的:由於默認的SynchronizationContext ,在控制台應用程序中,默認情況下,將繼續調度到線程池。

每個async方法的確會同步啟動,因此您的for循環將在同一線程上執行DoOpAsync的開頭。 假設SomeOperationAsync返回一個不完整的Task ,則繼續將在線程池中進行調度。

因此, DoOpAsync每個調用DoOpAsync可以並行進行。

暫無
暫無

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

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