假设服务器存储了一个ImmutableHashSet连接数据
ImmutableHashSet<ConnectionData> connections = new ...
然后我有各种各样的呼叫,可以从中添加/删除/读取,例如:
OnConnected(connectionData) => connections = connections.Add(connectionData);
OnDisconnected(connectionData) => connections = connections.Remove(connectionData);
我的问题是,在上述仅对HashSet进行单个操作(添加/删除)的调用中,我应该锁定连接吗?还是ImmutableHashSet操作线程安全吗?
答案 0 :(得分:7)
您将值直接分配回集合的模式不是线程安全的。但是,在使用不可变集合时,您通常不希望lock
。这些集合的主要功能之一是无锁操作,该锁通常具有更高的性能。而是使用ImmutableInterlocked
类:
ImmutableHashSet<ConnectionData> connections;
ImmutableInterlocked.Update(ref connections,
(collection, item) => collection.Add(item),
connectionData);
ImmutableInterlocked.Update(ref connections,
(collection, item) => collection.Remove(item),
connectionData);
答案 1 :(得分:1)
Add
和Remove
方法调用将返回全新的ImmutableHashSet
。因此,当类型为thread-safe时,您将需要使用锁定-处理同时发生对Add
或Remove
的多次调用的情况。 否则,如果同时发生两个Add
调用(例如),则您具有经典的比赛条件。
这样,您将要使用一个锁定对象:
private object lockObject = new lockObject();
,然后在分配给lock(lockObject)
的每个代码块周围使用connections
(例如您的Add
和Remove
调用)。
另请参阅上述评论中@ Flydog57提供的链接。