繁体   English   中英

在多线程环境中返回c#中的字典

[英]Returning a dictionary in c# in a multi-threaded environment

我已经宣布了一个词典的字典:

Dictionary<String, Dictionary<String, String>> values;

我有一个getter来获取特定索引的字典:

public Dictionary<String,String> get(String idx)
{
    lock (_lock)
    {
        return values[moduleName];
    }
}

如您所见,我正在多线程环境中工作。 我的问题是我需要返回我的字典的副本,以便像这样线程安全:

public Dictionary<String,String> get(String idx)
{
    lock (_lock)
    {
        return new Dictionary<string, string>(values[moduleName]);
    }
}

如果我不这样,那个调用getter的类会收到一个副本(所以如果我从我的Dictionary<String, Dictionary<String, String>>删除这个字典,它仍然可以工作)?

干杯,

蒂埃里。

Dictionary<>不是Thread安全的,但ConncurrentDictionary<>是。

调用getter的类接收一个引用,这意味着如果你从values -Dictionary中删除它仍然会存在,因为只要你在某个地方有一个引用,GC就不会清除它,你就是无法得到它得到了。

Basicaly表示使用Dictionary<>时有两种可能性:

  • 返回副本 :错误的想法,因为如果您更改配置,您的应用程序中有两个不同的配置“alive”
  • 锁定实例 :这会使它成为线程安全的,但是然后使用ConcurrentDictionary<>因为它完全适合你

如果你真的需要返回字典本身,那么你将需要有关于线程如何锁定它的规则(脆弱,如果有一个案例没有?),在只读中使用它方式(字典对于只读是线程安全的,但请注意,这假定该类的私有代码不再写入它),使用线程安全字典( ConcurrentDictionary使用条带锁定,我的ThreadSafeDictionary使用无锁方法,有不同的场景,其中一个击败另一个),或按照你的建议制作副本。

或者,如果您公开一个方法来检索或设置两个键找到的最终字符串,枚举键找到的二级键,依此类推,那么您不仅可以控制一个键完成的锁定但是它在界面清洁和从界面中释放实现方面有其他优势(例如,您可以从基于锁的移动到使用线程安全的字典,或者反过来,而不影响调用代码)。

如果您不返回副本,则调用者将能够更改字典,但这不是线程安全问题。

还存在线程安全问题,因为您没有公开任何锁来同步写入和读取。 例如,您的编写器线程可以在读取器线程处理同一实例时添加/删除值。

是的,你必须退回一份副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM