Блокировки в LINQ - помогите разобраться
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 01.02.11 10:26
Оценка:
Добрый день!

Имеется многопоточный сервер на FW3.5. Сервер в памяти хранит Dictionary<int, ClientSession> — коллекция объектов-клиентских сессий по неким идентификаторам. Любое обращение к коллекции обернуто в
lock (sessionsLockObject) { ..}.

Периодически этот участок кода захватывает блокировку и не отпускает:



List<MessageInfo> unsentMessages = new List<MessageInfo>();
lock (sessionsLockObject)
{
    List<MessageInfo> messages = new List<MessageInfo>();
    foreach (KeyValuePair<int, ClientSession> keyValuePair in sessions)
    {
        if (keyValuePair.Value.clientId == userInfo)
        {
            
             unsentMessages.AddRange(keyValuePair.Value.сессия.уведомления.Where(
                 messageInfo => (messageInfo.state != MessageState.Processed)));  
           
             sessions.Remove(keyValuePair.Key);                        
             break;
        }
    }

    sessions.Add(sessionId,
                             new ClientSession()
                                 {id = sessionId, loginTime = DateTime.Now,messages =  unsentMessages,...});                                     
}





Попытки отладки выявили, что при зависании выполнение доходит до выделенной строки и останавливается. Что может вызвать блокироку в этой строке?

Может, я что-то принципиально не так делаю?



PS В остальных местах в lock обернут такой код

//90%  просто перечисление
List<ClientSession> list;
lock (sessionsLockObject)
{
     list = sessions.Values.ToList();
}

lock (sessionsLockObject)
{
    if (sessions.ContainsKey(id))
    {

        sessions.Remove(id);       
    }
}
lock (sessionsLockObject)
{
     s = sessions.Values.Where(t => t.clientId == clientId).ToList();
}



Есть еще много обращений к коллекции по ключу без lock, например

 if (sessions.ContainsKey(id))
        sessionInfo  = sessions[id];
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.