【发布时间】:2021-10-14 09:23:14
【问题描述】:
我偶然发现了以下障碍。我需要有一个 ConcurrentDictionary
using System.Collections;
using System.Collections.Concurrent;
private ConcurrentDictionary<string, ArrayList> _data= new ConcurrentDictionary<string, ArrayList>();
private void AddData(string key, string message){
_data.AddOrUpdate(key, new ArrayList() { message }, (string existingKey, string existingList) => existingList.Add(message));
}
但是这种方法不起作用并抛出以下错误:
编译器错误 CS1661:无法将匿名方法块转换为委托类型“委托类型”,因为指定块的参数类型与委托参数类型不匹配
总之,我正在尝试执行以下操作:
- 尝试将消息添加到 ConcurrentDictionary 中的 arraylist。
- 如果 arraylist 不存在,则创建一个包含消息的新列表。
- 如果 arraylist 存在,只需将其添加到数组的末尾即可。
所以我的问题是,我该如何修复这个错误并改进我的代码,我做错了什么?
【问题讨论】:
-
专业提示,不要使用ArrayList,它是一个古老的遗物。网
-
您的 lambda 应该返回键的新值,而不仅仅是就地修改现有值。而且,即使你会返回修改后的值,恐怕这样的修改也不是线程安全的
-
您建议使用什么?
-
请不要使用相当复杂的集合,例如
ConcurrentDictionary,除非您已经很好地掌握了编写多线程代码,并且您了解其中的陷阱。例如,您没有考虑对 ArrayList 的任何修改也需要是线程安全的。使用Dictionary周围的简单锁可能会好得多 -
从集合的内部一致性的角度来看,并发集合的工厂参数是安全的,但是当存在争用时它们可以多次运行。没有内部锁钱包
标签: c# arrays multithreading thread-safety concurrentdictionary