Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为IDictionary,特别是ConcurrentDictionary实现RemoveAll?_C#_Exception_Concurrency - Fatal编程技术网

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)));
}