[英]Running synchronous method async
我有一個方法,該方法可以迭代對象列表,並且列表中的每個項目都可以從外部api獲取數據。
有時候(自然地),這可能會非常慢,我想將所有項目添加到Taks列表中,而不是能夠同時運行多個線程。 是否可以在不全部重寫的情況下實現異步? 今天,我正在使用WebClient並同步獲取所有內容。
我起初嘗試過這樣的事情:
public Main()
{
List<Task<Model>> taskList = new List<Task<Model>>();
foreach (var aThing in myThings)
{
taskList.Add(GetStuffAsync(aThing));
}
List<Model> list = Task.WhenAll(taskList.ToArray()).Result.ToList();
}
public async Task<Model> GetStuffAsync(object aThing)
{
// Stuff that is all synchronous
// ...
return anObject;
}
您可以僅使GetStuff
成為普通的同步方法,然后使用Task.Run
來創建新任務(通常將在多個線程上運行),而不是在此處使用異步,以便並行進行獲取。 您還可以考慮使用Parallel.ForEach
之類的東西,它實際上類似於當前的Main
代碼。
您的異步方法目前無法執行您想要的操作,因為異步方法至少在第一個await
表達式中同步運行...在您的情況下,您沒有任何await
表達式,因此在GetStuffAsync
返回時,它是已經完成了所有實際工作-您沒有並行性。
當然,一種替代方法是使用當前代碼,但實際上確實使GetStuffAsync
異步。
還需要記住的是,.NET中的HTTP堆棧具有按主機連接池的限制 -因此,如果您要從同一主機獲取多個URL,則可能還要增加這些URL,否則您將獲得的URL很少並行性。
試試這個概念:
foreach(var aThing in myThings)
{
Thread myTask = new Thread(new ParameterizedThreadStart(TaskMethod));
myTask.Start(aThing);
}
並且必須有一個名為TaskMethod
的方法,該方法void TaskMethod(object obj)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.