只允许管理员查看
现在,我希望允许管理员列出字典中的所有值,但是管理员将不会添加或删除项目,相反,我将仅提供一种方式,让管理员通过遍历以下内容来读取集合以查看项目这几项。
(伪)代码看起来像这样:
foreach (var e in EmployeeCache.Instance.AllEmployees)
{
Console.WriteLine(e.Key);
}
我的问题是:
如果我遍历项目,那么从中读取ConcurrentDictionary时是否将其锁定?换句话说,ConcurrentDictionary是否已锁定,以便在管理代码只是简单地通过ConcurrentDictionary进行迭代时,其他 session 将无法添加或删除?
如果未锁定,您能否解释
如果您认为它没有被锁定,能否简要概述一下它是如何进行的?
例如,它是否为只读操作创建ConcurrentDictionary的副本,然后允许读取迭代运行-了解不会看到对实际字典的并发更改?
我正在尝试确定
我试图了解提供ConcurrentDictionary查看器的影响,管理员可以经常刷新该查看器。 IE。如果他们经常刷新它,可能会影响Web应用程序的性能。由于 session 正在等待对象解锁,因此他们可以添加/删除项目?
最佳答案
这是 ConcurrentDictionary.GetEnumerator
的实现方式:
/// <remarks>
/// The enumerator returned from the dictionary is safe to use concurrently with
/// reads and writes to the dictionary, however it does not represent a moment-in-time
/// snapshot of the dictionary. The contents exposed through the enumerator may contain
/// modifications made to the dictionary after <see cref="GetEnumerator"/> was called.
/// </remarks>
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
Node[] buckets = m_tables.m_buckets;
for (int i = 0; i < buckets.Length; i++)
{
// The Volatile.Read ensures that the load of the fields of 'current'
// doesn't move before the load from buckets[i].
Node current = Volatile.Read<Node>(ref buckets[i]);
while (current != null)
{
yield return new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);
current = current.m_next;
}
}
}
如您所见,该迭代是无锁的,并且仅生成一个不变的结构(
KeyValuePair
),该结构将在每次迭代时返回给调用者。这就是为什么它不能保证ConcurrentDictionary
的实时快照的原因这绝对不会在迭代时添加/更新新值上产生性能影响,但是它不能保证您的管理员将看到词典的最新快照。
http://sourceof.net
关于c# - 遍历ConcurrentDictionary并且仅读取时,ConcurrentDictionary是否被锁定?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24247029/