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

时间:2011-05-20 18:02:54

标签: .net multithreading collections thread-safety in-memory-database

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

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

一个线程将其存储在集合中。 其他线程(3-10)按键(90%)和属性(10%)查询集合。

实施此项目的最佳方法是什么?如果我在收集中有10个,100个,1000个以上的项目?

3 个答案:

答案 0 :(得分:4)

如果您真的想要一个内存数据库,那么使用Sqlitemanaged data provider将是您的最佳选择。但是,我怀疑在这种情况下你可以使用ConcurrenctDictionary。此集合可以轻松处理1000多个项目,并且许多线程并行访问它。使用此集合的警告是,您只能为集合中的每个条目指定一个键。您可能需要为要查找的每个属性使用单独的集合。然后,如果属性的查找很少,那么您可以选择枚举整个集合以查找匹配的属性,而无需单独的集合。

答案 1 :(得分:4)

如果在初始化之后集合是不可变的(只读,永不更改),并且在任何线程可以到达之前初始化集合,则不需要执行任何特殊操作。多个线程可以同时从集合或字典中读取而没有任何问题。

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

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

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

答案 2 :(得分:0)

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

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

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

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

正如Brian Gideon建议的那样,你确实有一个DataSet的替代品 - 一个ConcurrentDictionary。

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

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