In SignalR ' Mapping Users to connections ' they have a pretty good implementation for mapping users to connections using Dictionary<T, HashSet<string>>
however, I can't see the point of this portion of code in the Add
method:
lock (connections)
{
connections.Add(connectionId);
}
1) What's the point of adding an element to the local variable connections
just before ending the method?
2) What's the point of having lock
inside a 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);
}
}
}
}
}
}
1) connections is a local variable, but actually is a reference to an object, the SAME object that was added to the *_connections* dictionary. So even when it seems to be only a "local variable" it's actually a reference to a managed object that won't be disposed at the end of the method because it is referenced in the dictionary.
2) I'm not sure if this is really necessary, but the outer "lock (_connection)" will lock the whole dictionary, and the lock (connection) will lock only the current hashset.
The add is important to add a new connectionId for an existing user.
User1, {Conn1}
User1, {Conn1, Conn2}
I'm not sure why you'd need to lock it twice.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.