並列プロセス集中的なIO関数
-
27-10-2019 - |
質問
このサンプルコードがあります。
List<Dictionary<string,string>> objects = new List<Dictionary<string,string>>();
foreach (string url in urls)
{
objects.add(processUrl(url))
}
URLを処理する必要があります、 processUrl
ページをダウンロードして多くのRegexを実行していくつかの情報を抽出し、「C#JSON like」オブジェクトを返します。したがって、これを類似点で実行したいので、最終的にオブジェクトのリストが必要なので、プロセスを継続するためにすべてのタスクを待つ必要があります、どうすればこれを達成できますか?私は多くの例を見ていますが、リターンを節約するものはありません。
よろしく
解決
このような?
var results = urls.AsParallel().Select(processUrl).ToList();
と Parallel
:
Parallel.ForEach(
urls,
url =>
{
var result = processUrl(url);
lock (syncOjbect)
objects.Add(result);
};
また
var objects = new ConcurrentBag<Dictionary<string,string>>();
Parallel.ForEach(urls, url => objects.Add(processUrl(url)));
var result = objects.ToList();
またはタスクで:
var tasks = urls
.Select(url => Task.Factory.StartNew(() => processUrl(url)))
.ToArray();
Task.WaitAll(tasks);
var restuls = tasks.Select(arg => arg.Result).ToList();
他のヒント
まず、ASをリファクタリングします
processUrl(url, objects);
結果をリストに追加する責任をタスクにします。
次に、2つの並列タスクが結果リストをまったく同じ時間に使用しようとしないように、ロックを追加します。
ノート: async
.NETの次のバージョンでのサポートにより、これが簡単に簡単になります。
Plinq拡張機能を使用できます。これには.NET 4.0が必要です
System.Threading.Tasks.Parallel
.ForEach(urls, url => {
var result = processUrl(url);
lock(objects)
{
objects.Add(result);
}
});
所属していません StackOverflow