我有一个很长的Excel文件,我使用EPPlus阅读。对于每一行,我测试它是否满足一定的标准,如果满足,我将该行(表示该行的对象)添加到集合中。当读取文件时,我将这些对象存储到数据库中。有可能同时做这两件事吗?我的想法是有一个对象集合,以某种方式将被线程消耗,并将对象保存到DB。同时,excel阅读器方法将填充集合…可以使用Rx还是有更好的方法?
谢谢。
另一个答案——基于对我第一个答案的评论。
创建一个从EPPlus/Xls返回IEnumberable<Records>
的函数-使用yield return
然后将这个序列转换为线程池中的一个可观察对象,这样你就得到了一个生产者/消费者和BlockingCollection的Rx方式。
function IEnumberable<Records> epplusRecords()
{
while (...)
yield return nextRecord;
}
var myRecords = epplusRecords
.ToObservable(Scheduler.ThreadPool)
.Where(rec => meetsCritera(rec))
.Select(rec => newShape(rec))
.Do(newRec => writeToDb(newRec))
.ToArray();
您的情况似乎是拉数据(IEnumerable
)而不是推数据(IObservable/Rx
)。因此,我建议LINQ对象是可以用来建模的解决方案。如下面的代码所示。
publis static IEnumerable<Records> ReadRecords(string excelFile)
{
//Read from excel file and yield values
}
//use linq operators to do filtering
var filtered = ReadRecords("fileName").Where(r => /*ur condition*/)
foreach(var r in filtered)
WriteToDb(r);
注意:在这种情况下,使用IEnumerable不需要创建中间集合,整个过程看起来像一个管道。
这似乎不太合适,因为在用例中没有固有的并发性、定时或事件。
也就是说,它可能是plinq的一个用例。如果EEPlus支持并发读取。就像
epplusRecords
.AsParallel()
.Where(rec => meetsCritera(rec))
.Select(rec => newShape(rec))
.Do(newRec => writeToDb(newRec))
.ToArray();