【问题标题】:c# multithreading file reading and page parsingc#多线程文件读取和页面解析
【发布时间】:2011-03-29 22:55:40
【问题描述】:

我有一个包含超过 500 000 个网址的文件。现在我想读取文件并使用返回字符串消息的函数解析每个 url。目前一切正常,但性能不佳,所以我需要在模拟线程(例如 100 个线程)中开始解析

ParseEngine parseEngine = new ParserEngine(parseFormulas);

StreamReader reader = new StreamReader("urls.txt");
String line = string.Empty;
while ((line = reader.ReadLine()) != null)
{
    string result = parseEngine.Parse(line);
    Console.WriteLine(result);
}
reader.Close();

如果我可以通过单击按钮来停止所有线程并更改线程数,那就太好了。有什么帮助和提示吗?

【问题讨论】:

  • 您使用的是哪个版本的 .NET?
  • 您是否使用 Parse 方法调用而不是 I/O 本身对性能造成影响?至少你应该做一些测量,看看你会通过多线程获得什么好处。
  • 4.0 版本。 Parse 方法最多需要 60 秒才能完成;页面下载、使用 html 敏捷包的 html 解析、正则表达式匹配和许多其他无需 I/O 的操作

标签: c# multithreading


【解决方案1】:

请务必查看 this article on PLINQ performance 与使用多线程逐行解析文本文件的其他技术的比较。

它不仅提供示例源代码来执行与您想要的几乎相同的操作,而且他们还发现了 PLINQ 的一个“陷阱”,它可能导致异常缓慢的时间。简而言之,如果您尝试使用 File.ReadAllLines() 或 StreamReader.ReadLine() 您将破坏性能,因为 PLINQ 无法以这种方式正确划分文件。他们通过将所有行读取到索引数组中解决了这个问题,然后使用 PLINQ 对其进行处理。

【讨论】:

    【解决方案2】:

    老实说,考虑到性能差异,如果可以的话,我会在 .net 4.0 中尝试并行 foreach。

     using System.Threading.Tasks;
    
      Parallel.ForEach(enumerableList, p =>{   
                 parseEngine.Parse(p);   
         });
    

    这是并行运行的一个不错的开始,应该可以最大程度地减少线程故障排除的麻烦。

    【讨论】:

      【解决方案3】:

      生产者/消费者设置对此有好处。一个线程从文件中读取并写入队列,其他线程可以从队列中读取。

      您提到了 100 个线程的示例。如果您有这么多线程,您可能希望分批从队列中读取,因为您可能必须在读取之前锁定队列,因为队列仅对单个读取器+写入器是线程安全的。

      我认为 4.0 中有一个新的 ConcurrentQueue 泛型,但我记不清了。

      你真的只想要一个文件阅读器。

      【讨论】:

        【解决方案4】:

        您可以使用 Parallel.ForEach() 为列表中的每个项目安排一个线程。假设 parseEngine 需要一些时间来运行,这会将线程分散到所有可用的处理器中。如果 parseEngine 运行得很快(定义为小于 250 毫秒),请通过调用 ThreadPool.SetMinThreads() 增加“按需”线程的数量,这将导致同时执行更多线程。

        【讨论】:

          猜你喜欢
          • 2019-06-02
          • 1970-01-01
          • 1970-01-01
          • 2012-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多