Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#并行更新词典条目?_C#_Dictionary_Parallel Processing - Fatal编程技术网

C#并行更新词典条目?

C#并行更新词典条目?,c#,dictionary,parallel-processing,C#,Dictionary,Parallel Processing,不知道这是否可行,但我想知道是否有可能并行执行此操作,而不是迭代字典并根据某些条件依次修改条目 例如,而不是: Dictionary<int, byte> dict = new Dictionary<int, byte>(); for (int i = 0; i < dict.Count; i++) { dict[i] = 255; } Dictionary dict=new Dictionary(); 对于(int i=0;ix,); 我意识到为了建立

不知道这是否可行,但我想知道是否有可能并行执行此操作,而不是迭代字典并根据某些条件依次修改条目

例如,而不是:

Dictionary<int, byte> dict = new Dictionary<int, byte>();
for (int i = 0; i < dict.Count; i++)
{
    dict[i] = 255;
}
Dictionary dict=new Dictionary();
对于(int i=0;i
我想要一些像:

Dictionary<int, byte> dict = new Dictionary<int, byte>();
dict.Parallel(x=>x, <condition>, <function_to_apply>);
Dictionary dict=new Dictionary();
dict.Parallel(x=>x,);
我意识到为了建立修改dict的索引,我们需要迭代并建立一个INT列表。。。但是,我想知道是否有一些鬼鬼祟祟的方法可以比第一个例子更快更简洁

当然,我可以迭代dict,为每个条目生成一个新的线程并运行一些代码,返回值并构建一个新的、更新的字典,但这似乎太过分了

我好奇的原因是
可能很贵

当然,我可以迭代dict,为每个条目生成一个新线程并运行一些代码,返回值并构建一个新的、更新的字典,但这似乎真的太过分了

假设您在重建字典时不需要它,那么它就没有那么多了:

var newDictionary = dictionary.AsParallel()
                              .Select(kvp => 
                                     /* do whatever here as long as
                                       it works with the local kvp variable
                                       and not the original dict */
                                     new
                                     {
                                          Key = kvp.Key,
                                          NewValue = function_to_apply(kvp.Key, kvp.Value)
                                     })
                                     .ToDictionary(x => x.Key,
                                                   x => x.NewValue);
然后锁定您需要的任何同步对象,并交换新字典和旧字典

当然,我可以迭代dict,为每个条目生成一个新线程并运行一些代码,返回值并构建一个新的、更新的字典,但这似乎真的太过分了

假设您在重建字典时不需要它,那么它就没有那么多了:

var newDictionary = dictionary.AsParallel()
                              .Select(kvp => 
                                     /* do whatever here as long as
                                       it works with the local kvp variable
                                       and not the original dict */
                                     new
                                     {
                                          Key = kvp.Key,
                                          NewValue = function_to_apply(kvp.Key, kvp.Value)
                                     })
                                     .ToDictionary(x => x.Key,
                                                   x => x.NewValue);

然后锁定您需要的任何同步对象并交换新旧词典。

首先,我同意其他人推荐的
ConcurrentDictionary
-它的设计是线程安全的

但是如果你是一个冒险的程序员;)性能对您来说非常关键,如果在并行操作过程中没有添加新键,也没有从字典中删除键,您有时可以尝试执行您(我想)正在尝试执行的

int keysNumber = 1000000;
Dictionary<int, string> d = Enumerable.Range(1, keysNumber)
                                .ToDictionary(x => x, x => (string)null);

Parallel.For(1, keysNumber + 1, k => { d[k] = "Value" + k; /*Some complex logic might go here*/ });
int-keysNumber=1000000;
字典d=可枚举的范围(1,键值)
.ToDictionary(x=>x,x=>(字符串)null);
Parallel.For(1,keysNumber+1,k=>{d[k]=“Value”+k;/*这里可能有一些复杂的逻辑*/});
要在这些操作后验证数据一致性,可以添加:

Debug.Assert(d.Count == keysNumber);
for (int i = 1; i <= keysNumber; i++)
{
    Debug.Assert(d[i] == "Value" + i);
}
Console.WriteLine("Successful");
Debug.Assert(d.Count==keysNumber);

对于(int i=1;i首先,我大部分同意其他人推荐的
ConcurrentDictionary
——它的设计是线程安全的

但是如果您是一个有冒险精神的程序员;)并且性能对您来说非常关键,您有时可以尝试做您(我想)正在尝试做的,以防在并行操作期间没有添加新键,也没有从字典中删除键:

int keysNumber = 1000000;
Dictionary<int, string> d = Enumerable.Range(1, keysNumber)
                                .ToDictionary(x => x, x => (string)null);

Parallel.For(1, keysNumber + 1, k => { d[k] = "Value" + k; /*Some complex logic might go here*/ });
int-keysNumber=1000000;
字典d=可枚举的范围(1,键值)
.ToDictionary(x=>x,x=>(字符串)null);
Parallel.For(1,keysNumber+1,k=>{d[k]=“Value”+k;/*这里可能有一些复杂的逻辑*/});
要在这些操作后验证数据一致性,可以添加:

Debug.Assert(d.Count == keysNumber);
for (int i = 1; i <= keysNumber; i++)
{
    Debug.Assert(d[i] == "Value" + i);
}
Console.WriteLine("Successful");
Debug.Assert(d.Count==keysNumber);

对于(int i=1;我不这样做。如果需要线程安全的集合,请使用ConcurrentDictionary。dictionary是可枚举的,因此可以在Parallel.Foreach中使用loop@Boo您永远不应该修改来自不同线程的IEnumerable。顺便问一下,为什么要像这样并行更新字典?您有多少条目,为什么您假设要更新di字典速度慢?根据您的场景,您可以并行运行
,然后“合并”结果在主线程中。不要这样做。如果您想要线程安全的集合,请使用ConcurrentDictionary。dictionary是可枚举的,因此可以在Parallel.Foreach中使用loop@Boo您永远不应该修改来自不同线程的IEnumerable。顺便问一下,为什么要这样并行更新字典?您有多少个条目,为什么假设更新字典时速度慢?根据您的场景,您可以并行运行
,然后“合并”结果在主线程中。您当然可以并行访问键,但问题是值不是一个不变的类型,最好创建一个本地值,然后像答案中那样分配给键@nvoigt@MrinalKamboj,我同意,但这主要是另一个话题,与二元数无关,这里没有人提到哪个值类型不使用OP。您当然可以并行访问键,但问题是值不是一个不可变的类型,最好创建一个本地值,然后按照@nvoigt@MrinalKamboj,我同意,但这主要是另一个话题,与二元数无关,这里没有人提到哪种值类型起作用使用。