TryRemove来自C#中ConcurrentDictionary的键值对

Fra*_*yce 3 c# concurrency concurrentdictionary

我的场景是我想要一个ConcurrentDictionary像这样的方法.

bool TryRemove(TKey key, TValue value) {
    // remove the value IF the value passed in == dictionary[key]
    // return false if the key is not in the dictionary, or the value is not equal
}
Run Code Online (Sandbox Code Playgroud)

有没有办法同时做到这一点?我很难找到这个场景的答案,尽管看起来这是一个常见的用例.

我可以做这样的事情,但如果我已经使用了,我想避免锁定ConcurrentDictionary.我还必须锁定GetOrAdd()AddOrUpdate()在其他地方打电话.似乎应该有一个更好的方法ConcurrentDictionary.

ConcurrentDictionary<int, string> dict = ...;

/// stuff

int keyTryToRemove = 1337;
string valTryToRemove = "someValue";

bool success = false;
lock(keyTryToRemove) {
    string val;
    if (dict.TryRemove(keyTryToRemove, out val)) {
        if (val == valTryToRemove) {
            success = true;
        }
        else { // reinsert value, UGLY!
            dict[keyTryToRemove] = val;
            success = false;
        }
    } else {
        success = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 5

因为ConcurrentDictionary<TKey, TValue>类实现(虽然是显式的)IDictionary<TKey, TValue>,因此ICollection<KeyValuePair<TKey, TValue>>,您可以简单地将它强制转换为后者并使用如下Remove方法:

bool success = ((ICollection<KeyValuePair<TKey, TValue>>)dict).Remove(
    new KeyValuePair<TKey, TValue>(key, value));
Run Code Online (Sandbox Code Playgroud)

实现内部使用相同的线程安全的方法(通过额外的价值进行检查)设置为公开TryRemove方法-也就是理所应当的.

编辑:一般来说,通过引入这样的自定义扩展方法,可以使任何类型的实现IDictionary<TKey, TValue>(或更精确地ICollection<KeyValuePair<TKey, TValue>>)类型的方法可用于该方法:DictionaryConcurrentDictionary

public static class Extensions
{
    public static bool TryRemove<TKey, TValue>(this ICollection<KeyValuePair<TKey, TValue>> source, TKey key, TValue value)
    {
        return source.Remove(new KeyValuePair<TKey, TValue>(key, value));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以示例代码变得简单:

bool success = dict.TryRemove(key, value);
Run Code Online (Sandbox Code Playgroud)

  • @JohnCarpenter - 它是,我刚刚检查过. (2认同)