.net 需要非常快速的线程安全收集或内存数据库

.net 需要非常快速的线程安全收集或内存数据库,.net,multithreading,collections,thread-safety,in-memory-database,.net,Multithreading,Collections,Thread Safety,In Memory Database,我从外部应用程序获取数据: class DataItem { public string key; public int Attribute1; public string Attribute2; } 类数据项 { 公共字符串密钥; 公共int属性1; 公共字符串属性2; } 一个线程将其存储在集合中。 其他线程(3-10)按键(90%)和属性(10%)查询集合 如果我的收藏中有10、100、1000多个项目,那么实现这一点的最佳方法是什么?如果您确实需要内存中的数据库,那么使

我从外部应用程序获取数据:

class DataItem { public string key; public int Attribute1; public string Attribute2; } 类数据项 { 公共字符串密钥; 公共int属性1; 公共字符串属性2; } 一个线程将其存储在集合中。 其他线程(3-10)按键(90%)和属性(10%)查询集合


如果我的收藏中有10、100、1000多个项目,那么实现这一点的最佳方法是什么?

如果您确实需要内存中的数据库,那么使用将是您的最佳选择。然而,我怀疑在这种情况下,你们会同意的。这个集合可以轻松地处理1000多个项目和并行访问它的多个线程。使用此集合的注意事项是,您只能为集合中的每个条目指定一个键。对于要查找的每个属性,可能需要使用单独的集合。同样,如果某个属性的查找次数不够频繁,那么您可以选择枚举整个集合以查找匹配的属性,而不需要单独的集合。

内存中的集合是只读的吗?它将改变你最终使用的东西

我的建议-
只读:使用ConcurrentDictionary
读写:使用数据集

在我看来,最好的并发或线程安全模型应该是数据集——请参阅:和。该数据集用于处理多个客户端的内存数据存储。请注意MSDN所说的内容:

此类型对于多线程读取操作是安全的。您必须同步所有写入操作。

正如Brian Gideon所建议的,您确实有一个数据集的替代品—ConcurrentDictionary

使用DataReader,您可以直接从DataReader填充自定义对象,如
DataItem


无论哪种方式,这两种解决方案都将允许您快速、并发地访问内存中的数据。

如果集合在初始化后是不可变的(只读的,从不更改),并且在任何线程可以访问它之前初始化了集合,则无需执行任何特殊操作。多个线程可以同时读取集合或字典,而不会出现任何问题

只有当共享对象(集合)由于多个线程的操作而更改状态时,才会出现问题。当多个线程从集合中读取时更新集合,或者如果集合维护内部缓存列表或诸如此类的内容,则会对多线程访问造成问题

如果将集合设置为在其静态构造函数中初始化的静态对象,则在初始化期间甚至不需要显式锁来保护集合。NET将保证在首次使用之前初始化该类


如果可以重新定义问题,使集合在初始化后是不可变的,那么就可以省去很多麻烦和工作量。

那么并发哈希映射呢?此外,您是否仅通过键或a1/a2进行查询?属性/键是否唯一?如果属性是不同的数据类型,则不能将它们全部用作单个字典中的键。但是,您可以为希望能够查询的每个属性数据类型创建单独的ConcurrentDictionary。如果Attrib是相同类型但不同的域,您也需要单独的字典。您可能仍然需要使用单独的字典。否则,您可能会得到与您不期望的属性匹配的结果。为什么ConcurrentDictionary需要是只读的?与数据集相比,ConcurrentDictionary具有以下优点:更快的查找速度,并且不需要手动同步读写操作(假设您没有修改字典中存储的各个值的属性)。@Joel:假设您没有修改字典中存储的各个值的属性。。。没错……我想我不应该假设这个字典中存储了不可变的类型。不过,这让事情变得简单多了——这并不意味着集合是只读的,因为您可以轻松地添加、删除或替换不可变值。@Joel:true。。。我不想对我的答案作任何假设,因为OP没有明确指定任何形式的不变性、只读性等。您可以维护两个集合:一个原件和一个副本。原件是动态的,副本总是只读的。当您想要发布原始集合的新状态时,只需复制它并将新引用分配给相应的变量即可。确保变量被标记为
volatile
,并且不需要进一步的同步机制。它适用于任何集合类型。@布赖恩:是的,当共享集合在使用中偶尔更新时,我已经多次使用了“两个列表”模式(不可变集合不需要两个列表)。使用InterlockedExchange交换列表指针,以保证全局指针变量的读修改写原子性。