Good day. I had the following task: I get a list of strings, then I create an instance of the class and call the method in it. At the moment, you need to parallelize this list, that is, processing in different threads. At the same time, a certain number of threads can be executed. As soon as one has finished, the next one is launched, and so on until the very end. I would do it on Parallel.Foreach , but the problem is that you need to do it on async/await . I found information on them, but I canβt understand how to work with them, because I find it easier to understand by reading the code. Please help.
- Strange your requirements. If you have a hard limit on the number of threads, where did async / await come from? Async / await does not give you control over threads, it is a higher level method. - VladD
- Well, if not, then how can this be implemented? - Dmitry Popov
|
1 answer
For example, this should work.
async Task ProcessTasks(IEnumerable<string> data, int maxParallelTasks) { var runningTasks = new HashSet<Task>(); foreach (var s in data) // ΡΠΈΠΊΠ» ΠΏΠΎ Π²ΡΠ΅ΠΌ ΡΡΡΠΎΠΊΠ°ΠΌ { // Π΄ΠΎΠΆΠ΄ΡΠΌΡΡ, ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΉΠ΄ΡΡΡΡ Β«ΠΌΠ΅ΡΡΠΎΒ» Π΄Π»Ρ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ while (runningTasks.Count >= maxParallelTasks) { // Π΄ΠΎΠΆΠ΄ΡΠΌΡΡ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΡ var firstFinishedTask = await Task.WhenAny(runningTasks); await firstFinishedTask; // Π΄ΠΎΡΡΠ°Π²ΠΈΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΄Π° runningTasks.Remove(firstFinishedTask); } // ΡΡΠ°ΡΡΡΠ΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅ runningTasks.Add(Task.Run(() => ProcessData(s)); } // Π΄ΠΎΠΆΠ΄ΡΠΌΡΡ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ Π²ΡΠ΅Ρ
Π·Π°ΠΏΡΡΠ΅Π½Π½ΡΡ
Π·Π°Π΄Π°Π½ΠΈΠΉ foreach (var task in runningTasks) await task; } If we put aside the hard limit on the number of simultaneous tasks, and entrust the TPL execution planning, a simpler code will do:
var tasks = data.Select(s => Task.Run(() => ProcessData(s))).ToList(); await Task.WhenAll(tasks); - Thank you so much, now everything is clear. - Dmitry Popov
- @DmitryPopov: Please! - VladD
|