我从外部应用程序获取数据:
类数据项 { 公共字符串密钥; 公共 int Attribute1; 公共字符串 Attribute2; }
一个线程将其存储在集合中。其他线程 (3-10) 通过键 (90%) 和属性 (10%) 查询集合。
如果我收集了 10、100、1000 多个项目,那么实施此操作的最佳方法是什么?
我从外部应用程序获取数据:
类数据项 { 公共字符串密钥; 公共 int Attribute1; 公共字符串 Attribute2; }
一个线程将其存储在集合中。其他线程 (3-10) 通过键 (90%) 和属性 (10%) 查询集合。
如果我收集了 10、100、1000 多个项目,那么实施此操作的最佳方法是什么?
如果您真的想要一个内存数据库,那么使用托管数据提供程序的Sqlite将是您的最佳选择。但是,我怀疑在这种情况下,您可以使用ConcurrenctDictionary。这个集合可以轻松处理 1000 多个项目和许多并行访问它的线程。使用此集合的注意事项是,您只能为集合中的每个条目指定一个键。您可能需要为要查找的每个属性使用单独的集合。再说一次,如果按属性查找的频率不够高,那么您可以选择枚举整个集合以查找匹配的属性,而无需单独的集合。
如果集合在初始化之后是不可变的(只读,永不改变),并且集合在任何线程可以访问它之前被初始化,那么您不需要做任何特殊的事情。多个线程可以同时从集合或字典中读取而不会出现任何问题。
只有当共享对象(集合)由于多个线程的操作而改变状态时才会出现问题。在多个线程从它读取时更新集合,或者如果集合维护内部缓存列表或诸如此类的东西会为多线程访问带来问题。
如果您将集合设置为在其静态构造函数中初始化的静态对象,那么您甚至不需要显式锁定来在初始化期间保护集合。.NET 将保证在第一次使用之前初始化该类。
如果您可以重新定义问题以便集合在初始化后是不可变的,那么您可以省去很多麻烦和工作。
内存中的集合是只读的吗?这将对您最终使用的内容产生影响。
我的建议 -
只读:使用 ConcurrentDictionary
读写:使用 DataSet
在我看来,最好的并发或线程安全模型是 DataSet - 请参阅:ADO.Net Tackle Data Concurrency和MSDN DataSet。DataSet 是为处理多个客户端的内存数据存储而开发的。请注意 MSDN 所说的:
这种类型对于多线程读取操作是安全的。您必须同步任何写入操作。
正如 Brian Gideon 建议的那样,您确实有一个 DataSet 的替代方案 - ConcurrentDictionary。
使用 DataReader,您可以DataItem
直接从 DataReader 填充自定义对象,例如 。
无论哪种方式,这两种解决方案都将允许您快速和并发地访问内存中的数据。