+-
CodeGo.net> C#-ConcurrentDictionary和原子操作-有时需要锁?
假设我有以下简单代码:(简化)

其中MyConCurrentDictionary是静态ConcurrentDictionary< string,string>. (位于不同的类中).

/*1*/   public void Send(string Message, string UserName)
/*2*/   {            
/*3*/       string ConnectionId;
/*4*/       if (MyConCurrentDictionary.TryGetValue(UserName,out ConnectionId))
/*5*/       {
/*6*/       //...   
/*7*/           DB.InsertMessage( Message, ConnectionId);
/*8*/           LOG.LogMessage  ( Message, ConnectionId);
/*9*/       //...
/*10*/       }
/*11*/       else ...
/*12*/   }

此方法可从许多实例运行. (signalR集线器,如果您愿意)

如果用户/连接ID存在,我只需要插入数据库/登录.

好的,所以当多线程正在访问ConcurrentDictionary时,第4行是线程安全的

但是还有另一个方法是RemoveUser-从字典中删除用户:

 public void RemoveUser (string userName)
        {
           string removed;
           if ( MyConCurrentDictionary.TryRemove(userName,out removed ))
              Clients.All.removeClientfromChat(userName);
        }

但是上下文可能会在第5行中出现,这将执行RemoveUser并从ConcurrentDictionary中删除UserName.

因此,为了解决此问题-代码将如下所示:

lock(locker)
{
  if (MyConCurrentDictionary.TryGetValue(UserName,out ConnectionId))
   {
    //...
   }

}

这完全违背了我的ConcurrentDictionary的目的.

在多线程环境中同时又受益于ConcurrentDictionary的正确方法是什么?

nb是,ConcurrentDictionary仅在字典中运行时才是线程安全的.但是我想说的是,在特定情况下,我失去了ConcurrentDictionary的好处,因为我仍然需要使用lock.(这可能是我错了).

最佳答案
根据您所写的内容和我到目前为止的了解:ConcurrentDictionary不是合适的选择!

写一个包装普通Dictionary的类,并封装ReaderWriterLockSlim的读写操作.这比普通锁快得多.同样,您一次可以进行多次读取,但一次只能进行一次写入操作.

private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

public void DoRead(string xyz)
{
    try
    {
        _lock.EnterReadLock();
        // whatever
    }
    finally
    {
        _lock.ExitReadLock();
    }
}

public void DoWrite(string xyz)
{
    try
    {
        _lock.EnterWriteLock();
        // whatever
    }
    finally
    {
        _lock.ExitWriteLock();
    }
}
点击查看更多相关文章

转载注明原文:CodeGo.net> C#-ConcurrentDictionary和原子操作-有时需要锁? - 乐贴网