并行foreach ConcurrentDictionary <string,string =“”> add </string,>

时间:2012-11-28 07:33:18

标签: c#-4.0 task-parallel-library concurrent-programming concurrent-collections

我有电话簿中的条目:姓名+地址。 来源在网站上,计数超过1K记录。

问题是:

如何在ConcurrentDictionary 中使用/实施 ParallelForeach

我不妨问它会更好地表现:

ConcurrentDictionary&amp; ParallelForeach

vs

Dictionary&amp; foreach

由于名称不允许重复是关键,我认为我理解正确ConcurrentDictionary有自己的内置函数要添加(TryAdd )仅当密钥不存在时。 所以不允许添加重复密钥的问题已经被关注,所以从那时起我可以清楚地看到余额转向ConcurrentDictionary而不是标准顺序Dictionary

那么如何添加名称&amp;来自任何给定数据源的地址,并通过Parallelforeach将其加载到ConcurrentDictionary

2 个答案:

答案 0 :(得分:2)

  

计数超过1K记录。

超过1K多少钱?因为1K记录会在眨眼之间添加,而不需要并行化。

此外,如果您通过网络获取数据,那么这个成本将大大使添加到字典的成本相形见绌。因此,除非您可以并行化获取数据,否则将数据并行添加到字典中会使代码更加复杂。

答案 1 :(得分:0)

这是一个古老的问题,但是可能会对某人有所帮助

如果您尝试对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,以免占用带宽。

Parallel.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