所以我在ConcurrentDictionary中有一个IList作为值.
ConcurrentDictionary> list1 = new ConcurrentDictionary >;
为了更新列表中的值,我这样做:
if (list1.ContainsKey[key]) { IListtemplist; list1.TryGetValue(key, out templist); templist.Add("helloworld"); }
但是,在templist中添加字符串是否会更新ConcurrentDictionary?如果是,那么更新是否是线程安全的,以便不会发生数据损坏?
或者是否有更好的方法来更新或创建ConcurrentDictionary中的列表
编辑
如果我使用ConcurrentBag而不是List,我将如何实现它?更具体地说,我该如何更新它?ConcurrentDictionary的TryUpdate方法感觉有点过分.
ConcurrentBag.Add是否在线程安全的mannar中更新ConcurrentDictionary?
ConcurrentDictionary> list1 = new ConcurrentDictionary >
Matthew Wats.. 5
首先,不需要执行ContainsKey()
和 TryGetValue()
。
您应该这样做:
IListtemplist; if (list1.TryGetValue(key, out templist)) templist.Add("helloworld");
实际上,您编写的代码具有竞争条件。
在一个线程调用ContainsKey()
与TryGetValue()
另一个线程之间可能已使用该键删除了该项目。然后TryGetValue()
将返回tempList
null,然后在调用时会得到null引用异常tempList.Add()
。
其次,是的:这里还有另一个可能的线程问题。您不知道IList
字典中存储的内容是线程安全的。
因此tempList.Add()
,不能保证通话安全。
您可以使用ConcurrentQueue
代替IList
。这可能将是最可靠的解决方案。
请注意,仅锁定访问权限IList
是不够的。
这不好:
if (list1.TryGetValue(key, out templist)) { lock (locker) { templist.Add("helloworld"); } }
除非您在IList
可能会访问的其他位置也使用相同的锁。这不容易实现,因此最好使用a ConcurrentQueue<>
或向此类添加锁定并更改体系结构,以使其他任何线程都不能访问基础IList。
首先,不需要执行ContainsKey()
和 TryGetValue()
。
您应该这样做:
IListtemplist; if (list1.TryGetValue(key, out templist)) templist.Add("helloworld");
实际上,您编写的代码具有竞争条件。
在一个线程调用ContainsKey()
与TryGetValue()
另一个线程之间可能已使用该键删除了该项目。然后TryGetValue()
将返回tempList
null,然后在调用时会得到null引用异常tempList.Add()
。
其次,是的:这里还有另一个可能的线程问题。您不知道IList
字典中存储的内容是线程安全的。
因此tempList.Add()
,不能保证通话安全。
您可以使用ConcurrentQueue
代替IList
。这可能将是最可靠的解决方案。
请注意,仅锁定访问权限IList
是不够的。
这不好:
if (list1.TryGetValue(key, out templist)) { lock (locker) { templist.Add("helloworld"); } }
除非您在IList
可能会访问的其他位置也使用相同的锁。这不容易实现,因此最好使用a ConcurrentQueue<>
或向此类添加锁定并更改体系结构,以使其他任何线程都不能访问基础IList。