2

我从外部应用程序获取数据:非常快线程安全的集合或内存数据库需要

 
class DataItem 
{ 
    public string key; 
    public int Attribute1; 
    public string Attribute2; 
} 

一个线程储存于收藏。 其他线程(3-10)通过键(90%)和属性(10%)查询集合。

什么是实现这个最好的方法如果我有10,100,1000+物品集合?

+0

并发哈希映射怎么样?你也只是通过键或a1/a2查询? – 2011-05-20 18:14:33

+0

是属性/关键唯一? – CodesInChaos 2011-05-20 18:40:08

回答

4

如果你真的想要一个内存数据库,然后Sqlite使用managed data provider将是你最好的选择。不过,我怀疑在这种情况下,你会好起来的ConcurrenctDictionary。这个集合可以很容易地处理1000多个项目和许多线程并行访问它。使用这个集合的警告是你可以只为集合中的每个条目指定一个键。您可能需要为要查找的每个属性使用单独的集合。再次,如果通过属性进行查找的次数不够多,那么您可以选择枚举整个集合以查找匹配的属性,而无需单独的集合。

+0

如果属性是不同的数据类型,则不能将它们全部用作单个字典中的键。但是,您可以为您希望能够查询的每个属性数据类型创建一个单独的ConcurrentDictionary。 – 2011-05-20 18:21:12

+0

如果attribs是相同的类型,但不同的域,你还需要单独的字典。 – 2011-05-20 18:26:54

+1

无论如何,您可能都想使用单独的字典。否则,你可以结束与你不期待的属性的匹配。 – 2011-05-20 18:31:02

0

内存集合是否是只读的?它会对你最终使用的内容产生影响。

我的建议 -
只读:使用ConcurrentDictionary
读&写:使用DataSet中

最好的并发,或线程安全的,模型,在我看来,将是数据集 - 请参阅:ADO.Net Tackle Data ConcurrencyMSDN DataSet。 DataSet的开发是为了处理多客户端的内存数据存储。注意MSDN说:

这种类型对于多线程安全的读取操作。您必须同步任何写入操作。

像Brian Gideon所建议的那样,您确实有一个DataSet的替代方案 - 一个ConcurrentDictionary。

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

无论哪种方式,这两种解决方案都可以让您快速并发地在内存中访问数据。

+0

为什么ConcurrentDictionary需要是只读的? ConcurrentDictionary比DataSet具有以下优点:更快的查找,并且不需要手动同步读取**或**写入(假设您不修改存储在字典中的单个值的属性)。 – 2011-05-20 18:33:37

+0

@Joel:*假设你没有修改存储在字典中的单个值的属性* ... ... – IAbstract 2011-05-20 20:11:34

+1

我想我不应该假设存储在这个字典中的不可变类型。不过,使事情变得如此简单 - 并不意味着集合是只读的,因为您可以轻松地添加,删除或替换不可变的值。 – 2011-05-20 21:03:08

4

如果集合在初始化后是不可变的(只读,永不改变),并且集合在任何线程可以到达之前被初始化,那么不需要做任何特殊的事情。多个线程可以同时从集合或字典中读取而不会有任何问题。

仅当共享对象(集合)由于多个线程的操作而改变状态时才会出现问题。当多个线程正在读取集合时更新集合,或者集合维护内部缓存列表或不会为多线程访问创建问题。

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

如果您可以重新定义问题以便集合在初始化后不可变,那么您可以节省很多头痛并工作。

+1

+1同意。您可以维护两个集合:原始文档和副本。原始文件是动态文件,副本始终为只读文件。当您想要发布原始集合的新状态时,只需将其复制并将新引用分配给相应的变量即可。确保变量标记为'volatile',并且不需要进一步的同步机制。它可以用于任何*集合类型。 – 2011-05-20 19:18:45

+0

@Brian:是的,当共享集合在使用中偶尔更新(两个列表对于不可变集合不需要)时,我多次使用了双列表模式。使用InterlockedExchange交换列表指针以保证全局指针var的读 - 修改 - 写原子性。 – dthorpe 2011-05-20 20:33:30