我只是将此代码用作示例。假设我有以下Person类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace dictionaryDisplay
{
class Person
{
public string FirstName { get; private set;}
public string LastName { get; private set; }
public Person(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public override string ToString()
{
return this.FirstName + " " + this.LastName;
}
}
}
主程序
static void Main(string[] args)
{
ConcurrentDictionary<int, Person> personColl = new ConcurrentDictionary<int, Person>();
personColl.TryAdd(0, new Person("Dave","Howells"));
personColl.TryAdd(1, new Person("Jastinder","Toor"));
Person outPerson = null;
personColl.TryRemove(0, out outPerson);
//Is this safe to do?
foreach (var display in personColl)
{
Console.WriteLine(display.Value);
}
}
这是对并发字典进行迭代的安全方法吗?如果没有,安全的方法是什么?
假设我想从字典中删除一个Person对象。我使用tryRemove方法,但我该如何处理outPerson对象?从字典中删除的Person存储在其中。如何处理outPerson对象以完全清除它?
这是对并发字典进行迭代的安全方法吗?如果没有,安全的方法是什么?
是的,它是安全的,因为它不会抛出异常。如果元素是在开始迭代后添加或删除的,那么它们可能会也可能不会包含在迭代中。来自GetEnumerator
文档:
从字典返回的枚举器可以安全地与对字典的读取和写入同时使用,但它并不代表字典的即时快照。通过枚举器公开的内容可能包含在调用GetEnumerator之后对字典所做的修改。
下一篇:
我使用tryRemove方法,但我该如何处理outPerson对象?
不管你想要什么,什么都不要。您可以将字典强制转换为IDictionary<TKey, TValue>
并调用Remove
,或者只使用TryRemove
然后忽略变量:
Person ignored;
dictionary.TryRemove(key, out ignored);
或者您可以使用C#7.0功能Discards
dictionary.TryRemove(key, out _);
没有"完全清除[对象]"的概念——如果你没有任何对它的引用,它将被垃圾收集。但不管怎样,它已经不在字典里了(至少通过那个键)。如果您不在代码中的任何其他地方使用变量(上面的ignored
),它不会阻止对象被垃圾收集。
看看这篇文章。
TryRemove() was added to attempt atomic, safe removes.
To safely attempt to remove a value we need to see if the key exists first, this checks for existence and removes under an atomic lock.
由于TryRemove将从集合中删除该项,因此您可能需要该键的值。
使用foreach迭代它是安全的。你不会有例外。