Firebird(.NET)的C#多线程数据库访问

时间:2010-11-06 00:45:06

标签: c# multithreading firebird threadpool

当我们将数据库中的数据写入我们自己的对象时,我想利用多线程。我们目前正在使用Firebird并使用“仅向前”阅读器FbDataReader检索数据。

我们遍历FbDataReader中保存的记录并填充对象,将对象添加到List,然后在应用程序中使用。所有这些都发生在我们应用程序的数据访问层中。

理想情况下,我们希望从数据库中检索数据(在FbDataReader中),然后在线程之间分割写入对象(每行一个)的工作。我看到的问题是FbDataReader只是前向的,不同的线程可能会导致读者在另一个线程完成之前执行下一个记录。

解决方案可能是将FbDataReader转储到索引的List,Array或Dictionary中,但这需要付出代价。

有没有人有任何想法,或者我们只是在浪费时间来重构这部分代码?

2 个答案:

答案 0 :(得分:0)

如果您可以获取不重叠的大块连续记录,并为每个记录分配数据读取器对象,那么您可以为每个读取器使用一个线程并获得收益,前提是数据源不会导致瓶子颈部。您基本上将使用多个读取器对象来代替中间存储。

e.g。

where ID >= 0 && ID < 10000   << block 1 for data reader instance 1
where ID >= 10000 && ID < 20000  << block 2 for data reader instance 2
where ID >= 20000 && ID < 30000  << block 3 for data reader instance 3

这三个读者的例子将允许您“同时”实例化三个对象。

如果另外使用围绕整个过程的C# iterator,您可能有办法返回所有对象,就像它们是单个集合一样,而不使用实例的任何中间存储。

foreach ( object o in MyIterator() ) { ....

即使它们是在不同的线程上创建的,这也会使对象回到单个线程使用的旗帜下。我只是在看最后一部分。

答案 1 :(得分:0)

您可以尝试创建新线程,并根据现有的连接字符串创建新的数据库连接。 在一个线程中,您可以处理偶数记录(2,4,6等),在另一个线程中可以处理奇数记录(1,3,5等)。 但是,这会增加代码的复杂性。

对于lenghty数据库操作,我更喜欢创建一个新的数据库连接对象,以便在单独的线程中完成工作并向用户显示进度,这样UI线程就不会冻结,应用程序仍然保持响应。