C# 不可变哈希集锁定

C# Immutable HashSet locking

假设服务器存储连接数据的 ImmutableHashSet

ImmutableHashSet<ConnectionData> connections = new ...

然后我收到各种电话 adding/removing/reading,即:

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

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

AddRemove 方法调用 return 一个全新的 ImmutableHashSet。因此,当类型为 thread-safe 时,您将需要使用锁定 - 来处理同时多次调用 AddRemove 的情况。 否则,如果两个 Add 调用同时发生(作为示例),您就会遇到典型的竞争条件。

因此,您需要使用锁对象:

private object lockObject = new lockObject();

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

另见@Flydog57 提供的精彩link 上述评论

您将值直接分配回集合的模式不是线程安全的。但是,在使用不可变集合时,您通常不希望 lock。这些集合的主要特征之一是无锁操作,这通常具有更高的性能。相反,使用 ImmutableInterlocked class:

ImmutableHashSet<ConnectionData> connections;

ImmutableInterlocked.Update(ref connections,
                            (collection, item) => collection.Add(item),
                            connectionData);

ImmutableInterlocked.Update(ref connections,
                            (collection, item) => collection.Remove(item),
                            connectionData);