C#不可变HashSet锁定

kof*_*fus 3 c# c#-7.0

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

ImmutableHashSet<ConnectionData> connections = new ...
Run Code Online (Sandbox Code Playgroud)

然后我有各种调用添加/删除/读取,即:

OnConnected(connectionData) => connections = connections.Add(connectionData);
OnDisconnected(connectionData) => connections = connections.Remove(connectionData);
Run Code Online (Sandbox Code Playgroud)

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

Cor*_*son 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);
Run Code Online (Sandbox Code Playgroud)

  • @kofifus Lock-free 更便宜,因为当争用率较低时,它平均会减少很多工作。在高争用期间,无锁仍然会更快,但速度会变慢——而且它会倾向于分配更多。幸运的是,这些分配都将在 gen-0 GC 中进行,这非常便宜。也就是说,如果您有高争用,那么无论锁定如何,不可变集合都不适合:它们不是为高写入争用而设计的。在这种情况下,您可能希望使用类似 `ConcurrentDictionary` 之类的东西,它支持实际的并发使用。 (2认同)