C# 如何为IDictionary,特别是ConcurrentDictionary实现RemoveAll?
我使用以下方法从C# 如何为IDictionary,特别是ConcurrentDictionary实现RemoveAll?,c#,exception,concurrency,C#,Exception,Concurrency,我使用以下方法从IDictionary中删除某些元素: public bool RemoveAll<TKey, TValue>(IDictionary<TKey, TValue> input, Func<KeyValuePair<TKey, TValue>, bool> predicate, Action<TKey, TValue> removalAction = null) { var result = false;
IDictionary
中删除某些元素:
public bool RemoveAll<TKey, TValue>(IDictionary<TKey, TValue> input, Func<KeyValuePair<TKey, TValue>, bool> predicate, Action<TKey, TValue> removalAction = null)
{
var result = false;
foreach (var kv in input.ToArray())
{
if (!predicate(kv)) continue;
removalAction?.Invoke(kv.Key, kv.Value);
input.Remove(kv.Key);
result = true;
}
return result;
}
如果TKey
是不可为空的类型,则不会出现这种情况
我的问题是:
- 为什么
,因为它是kv.Key==null
?input.ToList()的结果中存储的原始元素的结构(即副本?)
- AFAIK在
上迭代或调用ConcurrentDictionary
本身是线程安全的,可能会导致过时的结果,但不会崩溃(例如使用“在迭代时已修改集合”)。实现预期功能的线程安全方式是什么ToList()
- 关于
与Remove
:TryRemove
明确实现ConcurrentDictionary
IDictionary。通过内部调用
来移除TryRemove
- 感谢您注意到
错误result=false
- 不幸的是,使用
并不能解决这个问题,但感谢您提供的有趣见解李>ToArray
该问题被标记为重复,但链接的、假定的重复并没有解决主要问题:如何才能
kv.Key==null
?注释不用于扩展讨论;此对话已结束。评论不用于扩展讨论;这段对话已经结束。
public void RemoveAllFromConcurrentDictionary()
{
var d = new ConcurrentDictionary<string, int>();
for (int i = 0; i < 10000000; i++)
{
var key = i.ToString() ;
d.AddOrUpdate(key, k => i, (k, old) => i);
}
var tasks = new Task[]
{
Task.Run(() => RemoveAll(d,kv => kv.Value % 2 == 0)),
Task.Run(() => RemoveAll(d,kv => kv.Value % 3 == 0)),
Task.Run(() => RemoveAll(d,kv => kv.Value % 4 == 0)),
Task.Run(() => RemoveAll(d,kv => kv.Value % 5 == 0))
};
Task.WhenAll(tasks).Wait();
Console.WriteLine(string.Join("\n", d.Select(kv => kv.Key)));
}