C# 4.0 并行foreach ConcurrentDictionary<;字符串,字符串>;添加
我有类似电话簿中的条目:姓名+地址。 来源在一个网站上,数量超过1K条记录 问题是: 如何使用/实现C# 4.0 并行foreach ConcurrentDictionary<;字符串,字符串>;添加,c#-4.0,task-parallel-library,concurrent-programming,concurrent-collections,C# 4.0,Task Parallel Library,Concurrent Programming,Concurrent Collections,我有类似电话簿中的条目:姓名+地址。 来源在一个网站上,数量超过1K条记录 问题是: 如何使用/实现ConcurrentDictionary与ParallelForeach? 我不妨问一下,它的性能是否会更好: ConcurrentDictionary&ParallelForeach vs 字典&foreach 由于名称不允许有重复项作为键,而且我认为我正确理解了concurrentdirectionary有自己的内置功能,只有在键不存在时才添加(TryAdd)。 因此,不允许添加已处理的重复键
ConcurrentDictionary
与ParallelForeach
?
我不妨问一下,它的性能是否会更好:
ConcurrentDictionary
&ParallelForeach
vs
字典
&foreach
由于名称不允许有重复项作为键,而且我认为我正确理解了concurrentdirectionary
有自己的内置功能,只有在键不存在时才添加(TryAdd
)。
因此,不允许添加已处理的重复键的问题,因此从这一点上,我可以清楚地看到,平衡正在转向concurrentdirectionary
,而不是标准的顺序Dictionary
那么,如何从任何给定的数据源添加名称和地址,并通过Parallelforeach将其加载到ConcurrentDictionary中呢
计数超过1K记录
超过1公里多少钱?因为1K记录将在眨眼之间添加,而不需要任何并行化
此外,如果您通过网络获取数据,那么这一成本将大大低于添加到字典的成本。因此,除非您能够并行地获取数据,否则将数据并行添加到字典中的代码变得更加复杂是没有意义的。这是一个安静的老问题,但这可能会帮助某些人: 如果您试图通过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;
});
}
}
}
使用System.Collections.Generic;
使用System.Threading.Tasks;
使用System.Collections.Concurrent;
命名空间并发测试
{
公共类ConcurrentExample
{
ConcurrentExample()
{
ConcurrentDictionary ConcurrentPairs=新的ConcurrentDictionary();
Parallel.ForEach(ConcurrentPairs,(KeyValuePair)=>
{
//利用
string key=pair.key;
字符串值=pair.value;
});
}
}
}
我不认为您能够使用Parallel.ForEach插入到新字典中,除非您已经有了一个与迭代时长度相同的对象。i、 e.包含您想要下载并插入词典的文本文档URL的列表。如果是这样,那么您可以使用以下内容:
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);
});
}
}
}
使用System.Threading.Tasks;
使用System.Collections.Concurrent;
命名空间并发测试
{
公共类ConcurrentExample
{
ConcurrentExample()
{
ConcurrentDictionary ConcurrentPairs=新的ConcurrentDictionary();
ConcurrentBag WebAddresses=新ConcurrentBag();
Parallel.ForEach(WebAddresses,新的ParallelOptions{MaxDegreeOfParallelism=4},(字符串webAddress)=>
{
//从网址获取
字符串webText;
//尝试添加
ConcurrentPairs.TryAdd(webAddress,webText);
//GetOrUpdate
AddOrUpdate(webAddress,webText,(字符串键,字符串oldValue)=>webText);
});
}
}
}
如果从Web服务器访问,您可能希望增加或减少并行性的MaxDefreeOfParallelism,这样您的带宽就不会阻塞
Parallel.ForEach:
ParallelOptions:@JonSkeet,嘿,Jon,我已经通过扩展WebClient实现了抓取,在并行性方面做了一些额外的修改,ivoked通过并行任务获取多个数据源虽然现在只有一个数据源在讨论,那么我猜对了,在获取部分实际上没有什么可并行的吗?@JbobJohan:听起来像,除非你开始使用范围标头一次获取部分数据(这将是非常复杂的).我有时喜欢你在最后一句话中给出的极其复杂的关键词(当我在谷歌上写这个打开的新标签时,通过这些关键词我得到了一些想法)。。。例如,浏览器和文件下载程序正在使用它,那么它是否是一种在保留部分地图的同时对数据进行分区的方法…就像在bit torrent或类似程序中使用的一样。。。因此,如果请求是大数据,我可以使用它。。。我要读更多。。。