Добрый день!
Имеется многопоточный сервер на 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];