我正在构建一个控制台应用程序,需要处理大量的数据。
基本上,该应用程序从数据库中获取引用。对于每个引用,解析文件内容并进行一些更改。这些文件是HTML文件,并且该过程使用正则表达式替换来做繁重的工作(查找引用并将其转换为链接)。然后将结果存储在文件系统中并发送到外部系统。
如果我按顺序总结这个过程:
var refs = GetReferencesFromDB(); // ~5000 Datarow returned
foreach(var ref in refs)
{
var filePath = GetFilePath(ref); // This method looks up in a previously loaded file list
var html = File.ReadAllText(filePath); // Read html locally, or from a network drive
var convertedHtml = ParseHtml(html);
File.WriteAllText(destinationFilePath); // Copy the result locally, or a network drive
SendToWs(ref, convertedHtml);
}
我的程序可以正确运行,但速度很慢。因此我想并行化处理过程。
到目前为止,我添加了一个简单的AsParallel并行处理:
var refs = GetReferencesFromDB().AsParallel();
refs.ForAll(ref=>
{
var filePath = GetFilePath(ref);
var html = File.ReadAllText(filePath);
var convertedHtml = ParseHtml(html);
File.WriteAllText(destinationFilePath);
SendToWs(ref, convertedHtml);
});
这个简单的更改减少了处理时间(时间减少了25%)。但是,根据我的理解,并行化对于依赖I/O资源的并行化不会带来太多好处(或者更糟,会减少好处),因为I/O不会神奇地增加。
因此,我认为我应该改变我的方法,不是并行化整个过程,而是创建依赖链式排队任务。例如,我应该创建以下流程:
但是,我不知道如何实现这样的想法。 我觉得这将最终成为一组消费者/生产者队列,但是我没有找到正确的示例。 另外,我不确定是否会有好处。 谢谢建议。 [编辑] 实际上,我是使用c# 4.5的完美候选人......如果它已经发布了:) [编辑2] 另一件让我认为它没有正确并行化的事情是,在资源监视器中,我看到CPU、网络I/O和磁盘I/O的图表不稳定。当其中一个高时,其他则低至中等水平。排队读取文件。完成后,排队分析HTML。完成后,将两者发送到WS并本地写入。完成后,记录结果。
XXX-YYY(年份)-ZZZ-lg.ext
(不是所有部分都是必需的)。不过我可以想象,与整行 HTML 标记相比,针对单个节点进行测试会更有效率,不是吗?非常感谢您的建议。 - Steve B) );
node.InnerHtml = converted; } } return hDoc.DocumentNode.OuterHtml; }`。感谢您的分享。 - Steve B