起初我的想法就像"这是一个基于散列的数据类型,然后它是未分类的".
然后,由于我即将使用它,我深入研究了这个问题,发现这个类实现了IEnumerable,并且这个帖子也证实了可以迭代这种数据.
所以,我的问题是:如果我使用foreach的是ConcurrentDictionary哪个是我读取元素的顺序?
然后,作为第二个问题,我想知道它的接口继承的排序方法是否具有任何用途.如果我ConcurrentDictionary在新订单上调用排序方法会持续存在(例如传入foreach)?
希望我已经清楚了
我有一个字典,我想在foreach循环中修改它的值,但是,因为我的应用程序是时间关键的,我试图避免所有不必要的锁定开销.
var loopData = new Dictionary<int, List<string>>();
var results = new Dictionary<int, List<string>>();
/// loopData and results are both initialized
/// with same set of keys.
Parallel.ForEach(loopData, data =>
{
var list = data.Value;
/// manipulate list here
/// Is this safe?
results[data.Key] = list;
});
Run Code Online (Sandbox Code Playgroud)
标记命令是否安全?即,无需锁定即可读/写字典的不同键值对.
注1:我知道并发集合名称空间及其所有宏观集合.另外我知道我可以简单地lock使用突出显示的命令来确保它的安全性.如前所述,我的目标是尽可能避免不必要的开销.
注2:在此链接中提出了类似的问题.在该问题中,容器的项目在Parallel.ForEach循环内被修改.然而,这里我们没有修改键值对,因此容器是完整的,只有被指向的数据被改变.这使得它与上述问题不同.
更新
ConcurrentDictionary会增加最少的开销,但我想避免它,如果这是安全的.c# multithreading dictionary concurrentdictionary parallel.foreach
MSDN声明从字典返回的枚举器不代表字典的时刻快照.虽然在多线程环境中很少需要它,但如果有人想要,获取ConcurrentDictionary的即时快照的最佳方法是什么?
我对 C# 中的并发字典有疑问。
在另一个问题中,有人问我如何使用哈希集作为值的并发字典,但使用哈希集并不是一个好主意,最好使用并发字典作为值。所以我得到的解决方案是这样的:
var myDic = new ConcurrentDictionary<long, ConcurrentDictionary<int, byte>>();
myDic.AddOrUpdate(key,
_ => new ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(element, 0)}),
(_, oldValue) => {
oldValue.TryAdd(element, 0);
return oldValue;
});
Run Code Online (Sandbox Code Playgroud)
假设我有两个线程,其中“元素”在线程 A 中为 1,在线程 B 中为 2。
我怀疑这是否是线程安全的。我可能是错的,但我认为并发字典是这样工作的:
线程 A:尝试为键 1 插入元素 1。键 1 不存在,因此尝试使用并发字典插入键 1 ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(1, 0)。
线程B:尝试在key 1的字典中插入item 2。 线程A还在添加新的key/value,线程B认为key 1不存在,所以尝试将value添加ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(2, 0)到key 1中。
线程 A 完成以成功插入键/值对。
线程 B 试图完成,但现在键 1 存在,因为线程 A 插入了键 1。因此线程 B 无法插入键/值。
那么会发生什么?线程 …
如果值不存在,我想将其初始化为 0。否则它应该增加现有值。
ConcurrentDictionary<int, int> dic = new ConcurrentDictionary<int, int>();
dic.AddOrUpdate(1, 0, (key, old) => old++);
dic.AddOrUpdate(2, 0, (key, old) => old++);
Run Code Online (Sandbox Code Playgroud)
此时,字典的键为 1 和 2,每个值为 0。
dic.AddOrUpdate(1, 0, (key, old) => old++);
Run Code Online (Sandbox Code Playgroud)
此时,键 1 的值应该是 1,而键 2 的值应该是 0,但是,两者的值都是 0。知道为什么吗?
ConcurrentDictionary<int, int> dic = new ConcurrentDictionary<int, int>();
dic.AddOrUpdate(1, 2, (s, i) => 0);
dic.AddOrUpdate(2, 3, (s, i) => 0);
dic.AddOrUpdate(3, 1, (s, i) => 0);
dic.AddOrUpdate(4, 7, (s, i) => 0);
Run Code Online (Sandbox Code Playgroud)
我只想选择值大于5的键.我该怎么做?
我有一个场景,所有线程只会在字典中插入唯一键。换句话说,没有两个线程会插入相同的密钥。我也没有任何更新或读取操作。这只是插入。ConcurrentDictionary在这种情况下我需要吗?
假设我有一个ConcurrentDictionary:
var dict = new ConcurrentDictionary<string, someObject>();
dict.TryAdd("0_someA_someB_someC", obj0);
dict.TryAdd("1_someA_someB_someC", obj1);
dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);
Run Code Online (Sandbox Code Playgroud)
键中的<number>_是递增的并且是字典,不能保证元素是按顺序排列的。
现在,假设我想从字典中删除所有小于 的number项目2。我不知道这些键会是什么样子,只知道它们会以上面的数字为前缀。
如何从字典中删除键以小于值开头的所有元素2?
例如,此过程后生成的字典将如下所示:
dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);
Run Code Online (Sandbox Code Playgroud) 我在 web api 中使用了一个静态并发字典,它可以被用户访问。
我正在使用以下方法:这些方法都是线程安全的吗?或者我必须添加lock()即使它是ConccurentDictionary?
基本上,它是由整个用户访问的,然后它应该能够相应地工作,因为该字典包含每个用户的集合并且它依赖于此。
static ConcurrentDictionary<string, SApp> SAppFarm= new ConcurrentDictionary<string, SApp>();
.TryRemove(_sessionUser,out s);
.TryAdd(_sessionUser, r);
.GetOrAdd(sessionUser, application);
Run Code Online (Sandbox Code Playgroud) c# asp.net multithreading concurrentdictionary asp.net-web-api
如果你有这个:
var resultlist = new List<Dictionary<DateTime, double>>();
Parallel.ForEach(input, item =>
{
resultlist.Add(SomeDataDictionary(item));
});
Run Code Online (Sandbox Code Playgroud)
返回数据将按方法SomeDataDictionary返回数据的顺序排列,不会按输入顺序排列.
有没有办法保持输入的顺序?
或者是更改数据类型并使用Parallel.For循环然后将索引传递给某种类型的数组返回类型的唯一方法?
我不确定我是否完全理解TryGet方法。
它什么false时候完全返回——当内部锁被锁定时,这意味着while如果我想获得价值就应该使用(知道它在那里)?
或者这while以某种方式嵌入到这个函数内部并返回false手段 -字典中没有这样的键?
注意。这是否适用于ConcurrentDictionary-TryAdd等的所有其他方法?