我有一个超过500 000个网址的文件。现在我想读取文件并用我的函数解析每个url,返回字符串消息。现在每个人都工作正常但性能不好所以我需要在simulataneus线程中开始解析(例如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();
当我可以通过按钮单击并更改线程数来停止所有线程时,这将是很好的。任何帮助和提示?
答案 0 :(得分:2)
与使用多线程逐行解析文本文件的其他技术相比,请务必查看this article on PLINQ performance。
它不仅提供样本源代码,用于执行与您想要的几乎完全相同的操作,而且还发现了PLINQ的“陷阱”,可能导致异常缓慢的时间。简而言之,如果您尝试使用File.ReadAllLines()或StreamReader.ReadLine(),您将破坏性能,因为PLINQ无法正确地将文件分割。他们通过将所有行读入索引数组来解决问题,然后用PLINQ处理它。
答案 1 :(得分:1)
老实说,如果这是一个选项,我会尝试在.net 4.0中并行foreach。
using System.Threading.Tasks;
Parallel.ForEach(enumerableList, p =>{
parseEngine.Parse(p);
});
它是一个平行运行的良好开端,应尽量减少线程故障排除的麻烦。
答案 2 :(得分:1)
生产者/消费者设置对此有利。一个线程从文件读取并写入队列,其他线程可以从队列中读取。
你提到了100个线程的例子。如果您有这么多线程,您可能需要批量读取队列,因为您可能必须在读取之前锁定队列,因为队列只对单个读取器+编写器是线程安全的。
我认为4.0中有一个新的ConcurrentQueue泛型,但我不记得了。
你真的只想要一个读者到这个文件。
答案 3 :(得分:0)
您可以使用Parallel.ForEach()为列表中的每个项目安排一个线程。这会将线程分散到所有可用的处理器中,假设parseEngine需要一些时间来运行。如果parseEngine运行得非常快(定义为小于250ms),则通过调用ThreadPool.SetMinThreads()来增加“按需”线程的数量,这将导致一次执行更多线程。