[英]Running Async Foreach Loop C# async await
我正在努力掌握c#async等待的基本概念。
基本上我所擁有的是一個我需要處理的對象列表,處理包括迭代其屬性並連接字符串,然后創建一個新對象(在本例中稱為trellocard)並最終添加一個trellocards列表。
迭代需要很長時間,所以我想做的是異步處理多個對象。
我嘗試了多種方法,但基本上我想做這樣的事情。 (在下面的例子中我已經刪除了處理,只是把system.threading.thread.sleep(200)。我等待這不是一個異步方法,我可以使用tasks.delay,但重點是我的處理沒有有任何異步方法,我想只使用多個實例運行整個方法。
private async Task<List<TrelloCard>> ProcessJobs(IQueryable<IGrouping<CardGrouping, Job>> jobs)
{
List<TrelloCard> cards = new List<TrelloCard>();
foreach (var job in jobs.ToList())
{
card = await ProcessCards(job, cards); // I would like to run multiple instances of the processing
cards.add(card); //Once each instance is finshed it adds it to the list
}
private async Task<TrelloCard> ProcessCards(Job job)
{
System.Threading.Thread.Sleep(2000); //Just for examples sake
return new TrelloCard();
}
我正在努力掌握c#async等待的基本概念。
簡單的定義是,Async-Await是一部分.Net並發,可用於進行多個IO調用,並且在此過程中不會浪費用於計算操作的線程。 它就像調用數據庫,Web服務,網絡調用,文件IO一樣,所有這些都不需要當前的進程線程
在您目前的情況下,用例是:
這似乎是一個計算綁定操作,除非你正在做一個IO,對我來說似乎你正在遍歷一個內存對象,對於這種情況,更好的選擇是:
System.Collections.Concurrent
命名空間中的ConcurrentBag
,或者適合用例而不是List<TrelloCard>
,或者您可以考慮遵循線程安全列表 另請注意,如果您的方法不是默認的Async
,那么您可能計划將它們包裝在Task.Run
, await
,雖然這需要一個線程池線程,但可以使用Async-Await
調用
Parallel.Foreach
代碼用於你的用例(我正在做直接替換,你的代碼似乎有問題,因為ProcessCards
函數,只需要Job對象,但你也傳遞了收集Cards
,這是編譯錯誤):
private List<TrelloCard> ProcessJobs(IQueryable<IGrouping<CardGrouping, Job>> jobs)
{
ConcurrentBag<TrelloCard> cards = new ConcurrentBag<TrelloCard>();
Parallel.ForEach(jobs.ToList(), (job) =>
{
card = ProcessCards(job); // I would like to run multiple instances of the processing
cards.Add(card); //Once each instance is finshed it adds it to the list
});
return cards.ToList();
}
private TrelloCard ProcessCards(Job job)
{
return new TrelloCard();
}
如果您希望它們並行運行,您可以為每個操作生成一個新任務,然后使用Task.WhenAll
等待所有操作的完成。
private async Task<List<TrelloCard>> ProcessJobs(IQueryable<IGrouping<CardGrouping, Job>> jobs)
{
List<Task<TrelloCard>> tasks = new List<Task<TrelloCard>>();
foreach (var job in jobs)
{
tasks.Add(ProcessCards(job));
}
var results = await Task.WhenAll(tasks);
return results.ToList();
}
private Task<TrelloCard> ProcessCards(Job job)
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(2000); //Just for examples sake
return new TrelloCard();
});
}
jobs.ToList()
只是在浪費內存。 它已經是IEnumerable
所以可以在foreach
。
ProcessCards
無法編譯。 你需要這樣的東西
private Task<TrelloCard> ProcessCards(Job job)
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(2000); //Just for examples sake
return new TrelloCard();
});
}
現在你想要ProcessJobs
返回一系列TrelloCard
private async Task<List<TrelloCard>> ProcessJobs(IQueryable<IGrouping<CardGrouping, Job>> jobs) { return await Task.WhenAll(jobs.Select(ProcessCards)); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.