我总是对选择哪一个感到困惑.当我看到它,我用Dictionary了List,如果我想两个数据类型为Key和Value这样我就可以很容易地找到它的价值key,但我总是困惑,如果我要使用一个ConcurrentDictionary或Dictionary?
在我离开之前没有对此进行太多研究之前我已经尝试过,但似乎谷歌并没有真正得到任何关于Dictionaryvs ConcurrentDictionary但是每个人都有一些东西.
我之前曾问过这样的朋友,但他们所说的只是:" ConcurrentDictionary如果你在代码中使用了很多字典就会使用",我真的不想纠缠他们来更详细地解释它.任何人都可以扩展这个吗?
正如MSDN所说
ConcurrentDictionary<TKey, TValue> Class表示可以由多个线程同时访问的键值对的线程安全集合.
但据我所知,System.Collections.Concurrent课程是为PLINQ设计的.
我有Dictionary<Key,Value>保持服务器中的在线客户端,并且当我有权访问它时通过锁定对象使其成为线程安全的.
我可以放心地取代Dictionary<TKey,TValue>通过ConcurrentDictionary<TKey,TValue>我的情况?更换后性能会提高吗?
这里在第5约瑟夫阿尔巴哈利提到,它专为并行编程
在上个月,我们的ASP.NET Web应用程序已停止响应请求,我们不得不重置应用程序池以使其备份.
我们无法确定问题的确切原因,因为服务器的事件日志中没有错误.该网站只是停止响应.
因此,我们一直在使用WinDbg来尝试分析在Tess Ferrandez的博客条目帮助下网站没有响应的内存转储:GC挂起和高CPU挂起
通过运行,!threadpool我可以看到以下内容:
CPU utilization: 81%
Worker Thread: Total: 10 Running: 8 Idle: 2 MaxLimit: 400 MinLimit: 160
Work Request in Queue: 1930
--------------------------------------
Number of Timers: 72
--------------------------------------
Completion Port Thread:Total: 1 Free: 1 MaxFree: 8 CurrentLimit: 0 MaxLimit: 400 MinLimit: 120
Run Code Online (Sandbox Code Playgroud)
根据Tess在悬挂博客文章中的说法,这表明我们陷入垃圾收集的中间(通常需要纳秒时间),因为处理器显示81%,这是.NET框架设置的内容虽然这是垃圾收集.它设置为this,因为当此值大于80%时,不会生成新线程.此外 - 您可以看到队列中有1930个请求,即使可能有400个工作线程只有10个.
通过运行该!threads命令,我可以看到两个PreEmptive GC设置为禁用的线程:
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
10 1 18bc 00000000001b9710 …Run Code Online (Sandbox Code Playgroud) 假设我有一个充当数据缓存的单例类.多个线程将从缓存中读取,并且单个线程将定期刷新它.它看起来像这样:
public sealed class DataStore
{
public static DataStore Instance { get { return _instance; } }
public Dictionary<Foo, Bar> FooBar { get; private set; }
static DataStore() { }
private DataStore() { }
public void Refresh() {
FooBar = GetFooBarFromDB();
}
private static readonly DataStore _instance = new DataStore();
}
Run Code Online (Sandbox Code Playgroud)
我的问题基本上是Refresh(),其他线程可能访问时FooBar是否安全?我需要使用锁,还是我的获取和设置操作是原子的?我是否需要显式声明volatile字段来备份我的属性?
PS,如果有人能想到这个问题的更具描述性的标题,我很乐意欢迎它.
编辑:修复了我的例子来明显纠正非原子代码.
我有一个场景,所有线程只会在字典中插入唯一键。换句话说,没有两个线程会插入相同的密钥。我也没有任何更新或读取操作。这只是插入。ConcurrentDictionary在这种情况下我需要吗?
c# ×5
dictionary ×4
.net ×3
asp.net ×1
c#-4.0 ×1
concurrency ×1
debugging ×1
hang ×1
windbg ×1