C#不可变HashSet锁定

时间:2018-07-20 03:27:22

标签: c# c#-7.0

假设服务器存储了一个ImmutableHashSet连接数据

ImmutableHashSet<ConnectionData> connections = new ...

然后我有各种各样的呼叫,可以从中添加/删除/读取,例如:

OnConnected(connectionData) => connections = connections.Add(connectionData);
OnDisconnected(connectionData) => connections = connections.Remove(connectionData);

我的问题是,在上述仅对HashSet进行单个操作(添加/删除)的调用中,我应该锁定连接吗?还是ImmutableHashSet操作线程安全吗?

2 个答案:

答案 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)

AddRemove方法调用将返回全新的ImmutableHashSet。因此,当类型为thread-safe时,您将需要使用锁定-处理同时发生对AddRemove的多次调用的情况。 否则,如果同时发生两个Add调用(例如),则您具有经典的比赛条件。

这样,您将要使用一个锁定对象:

private object lockObject = new lockObject();

,然后在分配给lock(lockObject)的每个代码块周围使用connections(例如您的AddRemove调用)。

另请参阅上述评论中@ Flydog57提供的链接。

相关问题