[英]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.