在SignalR'Mapping Users to connections'中,他们使用Dictionary<T, HashSet<string>>
将用户映射到连接有一个非常好的实现但是,我无法在Add
中看到这部分代码的重点方法:
lock (connections)
{
connections.Add(connectionId);
}
1)在结束方法之前,将一个元素添加到局部变量connections
有什么意义?
2)lock
内有lock
是什么意思?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TraQ6.GeoTrack
{
public class ConnectionMapping<T>
{
private readonly Dictionary<T, HashSet<string>> _connections =
new Dictionary<T, HashSet<string>>();
public int Count
{
get
{
return _connections.Count;
}
}
public void Add(T key, string connectionId)
{
lock (_connections)
{
HashSet<string> connections;
if (!_connections.TryGetValue(key, out connections))
{
connections = new HashSet<string>();
_connections.Add(key, connections);
}
lock (connections) // here
{
connections.Add(connectionId); // here
}
}
}
public IEnumerable<string> GetConnections(T key)
{
HashSet<string> connections;
if (_connections.TryGetValue(key, out connections))
{
return connections;
}
return Enumerable.Empty<string>();
}
public void Remove(T key, string connectionId)
{
lock (_connections)
{
HashSet<string> connections;
if (!_connections.TryGetValue(key, out connections))
{
return;
}
lock (connections)
{
connections.Remove(connectionId);
if (connections.Count == 0)
{
_connections.Remove(key);
}
}
}
}
}
}
答案 0 :(得分:1)
1) connections 是一个局部变量,但实际上是对象的引用,即添加到* _connections *字典的SAME对象。 因此,即使它看起来只是一个“局部变量”,它实际上也是对托管对象的引用,因为它在字典中被引用,所以它不会被放置在方法的末尾。
2)我不确定这是否真的有必要,但外部的“lock(_connection)”将锁定整个字典, lock(连接)将仅锁定当前的hashset
答案 1 :(得分:0)
添加对于为现有用户添加新的connectionId很重要。
User1, {Conn1}
User1, {Conn1, Conn2}
我不确定为什么你需要锁定它两次。