概要
Parallel.ForEach
のdelegate上でawaitを使いたいのですが、
すべての処理が実行されずにParallel.ForEach
が抜けてしまいます。
Parallel.ForEach
のdelegate上では同期処理を書かなくてはならないのでしょうか。
背景
listのデータに対して順序にかかわらず上限のある並列数(1~)で実行したい。
システム全体でのスレッドの上限があるため、極力節約したい。
※目くじら立てる程でもないのかもしれませんが、ほとんどの処理をAsync化してしまったので、wait等は避けようとしてどうしてこうなった。
(追記 2020/01/15 21:15 JST)
なぜParallel.ForEachを使い、並列数を指定しているのかの、説明ができていませんでした。
ループ処理内でネットワーク通信を挟んでいるためです:
ネットワーク通信先では同時接続数の上限もあるため、同時アクセス数の制限を設けたい。(Server busyとなってしまう)
なお、ネットワーク接続先は複数箇所であるため、クライアント側のソケットも使い果たすとマズイため、一部処理を並列化し、終了を簡単に待つことができる機構を求めた結果、この質問になってしまいました。
環境
- .NET Framework 4.5.2
- VisualStudio 2015 Community Edition
- Windows 10 home
もしくは
- .NET Core 2.2
- VisualStudio 2017 Professional
- Windows 10 Pro
備考(オフトピック)
コード確認はできていませんが、Task.Wait()
メソッド(引数無し)では通常、呼び出し元スレッドを維持してしまう認識であっているか、教えていただける幸いです。
検証
コード
cs
1using System; 2using Microsoft.VisualStudio.TestTools.UnitTesting; 3using System.Collections.Generic; 4using System.Threading.Tasks; 5using System.Threading; 6using System.Diagnostics; 7using System.Collections; 8using System.Linq; 9 10namespace ParallelTest 11{ 12 [TestClass] 13 public class UnitTest1 14 { 15 [TestMethod] 16 public void TestMethod1() 17 { 18 var list = Enumerable.Range(1, 30).ToList(); 19 ParallelFor(10, list, async (item) => 20 { 21 Trace.TraceInformation("Inner start {0}", item); 22 await Task.Delay(100); 23 Trace.TraceInformation("Inner end {0}", item); 24 }); 25 26 } 27 /// <summary> 28 /// 同時実行数制限付き並列動作 29 /// </summary> 30 /// <typeparam name="T">リストのデータタイプ</typeparam> 31 /// <param name="degree">並列数</param> 32 /// <param name="list">並列処理するリスト</param> 33 /// <param name="task">並列処理内容</param> 34 static void ParallelFor<T>(int degree, IList<T> list, Func<T,Task> task) 35 { 36 Trace.TraceInformation("Enter"); 37 Parallel.ForEach(list, new ParallelOptions (){ MaxDegreeOfParallelism = degree }, async (data) => 38 { 39 Trace.TraceInformation("Task start {0}", data); 40 await task(data); 41 Trace.TraceInformation("Task end {0}", data); 42 }); 43 Trace.TraceInformation("End"); 44 } 45 } 46} 47
結果
Task endが呼び出されることなく、終了してしまう。
txt
1Enter 2Task start 10 3Task start 4 4Inner start 10 5Task start 7 6Inner start 7 7Task start 13 8Task start 1 9Inner start 1 10Inner start 4 11Task start 8 12Inner start 8 13Task start 9 14Inner start 9 15Task start 14 16Inner start 14 17Task start 11 18Inner start 11 19Task start 12 20Inner start 12 21Inner start 13 22Task start 19 23Inner start 19 24Task start 20 25Inner start 20 26Task start 21 27Inner start 21 28Task start 22 29Inner start 22 30Task start 16 31Inner start 16 32Task start 17 33Inner start 17 34Task start 18 35Inner start 18 36Task start 25 37Inner start 25 38Task start 26 39Inner start 26 40Task start 27 41Inner start 27 42Task start 28 43Inner start 28 44Task start 2 45Inner start 2 46Task start 3 47Inner start 3 48Task start 23 49Inner start 23 50Task start 29 51Inner start 29 52Task start 30 53Inner start 30 54Task start 5 55Inner start 5 56Task start 6 57Inner start 6 58Task start 24 59Inner start 24 60Task start 15 61Inner start 15 62End
回答6件
あなたの回答
tips
プレビュー