use*_*331 103 c# concurrent-collections
我试图使用Dictionary重新编写一些代码来使用ConcurrentDictionary.我已经回顾了一些示例,但我仍然无法实现AddOrUpdate函数.这是原始代码:
dynamic a = HttpContext;
Dictionary<int, string> userDic = this.HttpContext.Application["UserSessionList"] as Dictionary<int, String>;
if (userDic != null)
{
if (useDic.ContainsKey(authUser.UserId))
{
userDic.Remove(authUser.UserId);
}
}
else
{
userDic = new Dictionary<int,string>();
}
userDic.Add(authUser.UserId, a.Session.SessionID.ToString());
this.HttpContext.Application["UserDic"] = userDic;
Run Code Online (Sandbox Code Playgroud)
我不知道要为更新部分添加什么:
userDic.AddOrUpdate(authUser.UserId,
a.Session.SessionID.ToString(),
/*** what to add here? ***/);
Run Code Online (Sandbox Code Playgroud)
任何指针将不胜感激.
M4N*_*M4N 210
您需要传递a Func,以便在更新时返回要存储在字典中的值.我想在你的情况下(因为你不区分添加和更新)这将是:
var sessionId = a.Session.SessionID.ToString();
userDic.AddOrUpdate(
authUser.UserId,
sessionId,
(key, oldValue) => sessionId);
Run Code Online (Sandbox Code Playgroud)
即Func始终返回sessionId,以便Add和Update都设置相同的值.
顺便说一句:MSDN页面上有一个示例.
Nik*_*ter 60
我希望,我在你的问题中没有遗漏任何内容,但为什么不这样呢?它更容易,原子和线程安全(见下文).
userDic[authUser.UserId] = sessionId;
Run Code Online (Sandbox Code Playgroud)
无条件地将键/值对存储到字典中,如果该键已存在,则覆盖该键的任何值:使用索引器的setter
(见:http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx)
索引器也是原子的.如果你传递一个函数,它可能不是:
所有这些操作都是原子的,并且对于ConcurrentDictionary上的所有其他操作都是线程安全的.对每个操作的原子性的唯一警告是那些接受委托的人,即AddOrUpdate和GetOrAdd.[...]这些委托在锁之外被调用
请参阅:http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx
ste*_*ook 26
我最终实现了一个扩展方法:
static class ExtensionMethods
{
// Either Add or overwrite
public static void AddOrUpdate<K, V>(this ConcurrentDictionary<K, V> dictionary, K key, V value)
{
dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
}
}
Run Code Online (Sandbox Code Playgroud)