问题是:
我如何使用/实现 ConcurrentDictionary
与ParallelForeach
?
[ConcurrentDictionary
&ParallelForeach
vs
[Dictionary
&foreach
由于名称
不允许重复
是密钥,我想我正确理解,ConcurrentDictionary
仅在不存在密钥的情况下才具有自己的内置函数来添加(TryAdd
)。因此,不允许添加已经处理过的重复密钥的问题,因此从这一点上我可以清楚地看到,余额正在转向ConcurrentDictionary
而不是标准顺序Dictionary
所以我如何从任何给定的数据源添加名称和地址,并通过Parallelforeach将其加载到ConcurrentDictionary中计数超过1K条记录。
超过1K?因为一眨眼就可以添加1K记录,而无需并行化。
此外,如果您要通过网络获取数据,则该费用
非常将使添加到词典中的费用相形见war。因此,除非可以并行化fetching数据,否则将代码复杂化以将数据并行添加到字典中将毫无意义。
如果您尝试对ConcurrentDictionary进行分块并进行一些处理:
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace ConcurrenyTests
{
public class ConcurrentExample
{
ConcurrentExample()
{
ConcurrentDictionary<string, string> ConcurrentPairs = new ConcurrentDictionary<string, string>();
Parallel.ForEach(ConcurrentPairs, (KeyValuePair<string, string> pair) =>
{
// Do Stuff with
string key = pair.Key;
string value = pair.Value;
});
}
}
}
我认为您无法使用Parallel.ForEach插入新字典中,除非您已有与迭代相同长度的对象。即包含您要下载并插入字典中的文本文档网址的列表。如果真是这样,那么您可以使用类似以下内容的东西:
using System.Threading.Tasks; using System.Collections.Concurrent; namespace ConcurrenyTests { public class ConcurrentExample { ConcurrentExample() { ConcurrentDictionary<string, string> ConcurrentPairs = new ConcurrentDictionary<string, string>(); ConcurrentBag<string> WebAddresses = new ConcurrentBag<string>(); Parallel.ForEach(WebAddresses, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (string webAddress) => { // Fetch from webaddress string webText; // Try Add ConcurrentPairs.TryAdd(webAddress, webText); // GetOrUpdate ConcurrentPairs.AddOrUpdate(webAddress, webText, (string key, string oldValue) => webText); }); } } }
如果从Web服务器进行访问,则可能希望增加或减少MaxDefreeOfParallelism,以免占用带宽。并行ForEach:https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel.foreach?view=netcore-2.2
ParallelOptions:https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=netcore-2.2