【发布时间】:2014-10-01 12:38:15
【问题描述】:
我目前正在尝试遍历一个大小约为 1.5gb 的文本文件,然后使用从中获取的 URL 从站点中提取 html。
为了速度,我试图在一个新线程上处理所有 HTTP 请求,但由于 C# 不是我最强大的语言,而是我正在做的事情的要求,所以我对良好的线程实践有点困惑。
这就是我处理列表的方式
private static void Main()
{
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead("dump.txt"))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize))
{
String line;
var progress = 0;
while ((line = streamReader.ReadLine()) != null)
{
var stuff = line.Split('|');
getHTML(stuff[3]);
progress += 1;
Console.WriteLine(progress);
}
}
}
我正在拉下 HTML
private static void getHTML(String url)
{
new Thread(() =>
{
var client = new DecompressGzipResponse();
var html = client.DownloadString(url);
}).Start();
}
虽然最初这样做的速度很快,但在大约 20000 之后它们会变慢,最终在 32000 之后应用程序将挂起并崩溃。我的印象是函数完成时 C# 线程终止了?
任何人都可以就如何更好地做到这一点提供任何示例/建议吗?
【问题讨论】:
-
20k 线程在任何语言中都是一个坏主意。您不能仅仅创建更多线程并获得性能的线性增益,这不是 CPU 的工作方式。此外,您的线程不会产生任何东西。他们只是下载一个字符串,该字符串会立即被丢弃,因为它是函数本地的。您需要以合理的大小批量处理这些请求。
-
您可能希望考虑限制活动线程的数量。您可以读取文件并创建新线程,速度远远快于它们完成的速度。
-
@EdS。出于测试目的,我无论如何都没有返回字符串,只是通过创建我每秒能够处理几千个的线程来查看下载 html 的请求可以多快,而不用线程化它不合理的慢;然而。正如我在最初的帖子中所说,我认为他们会在功能完成后自我毁灭。你有关于如何解决这个问题的代码示例吗?
-
@user3037561:线程在退出后被销毁,这不是你的问题。您的问题是同时启动如此大量的它们。不要期望它们以同步方式运行和完成。你在折腾。线程是昂贵的资源。
-
@EdS。据我所知,但不幸的是,我不知道如何以符合 c# 标准或至少产生高质量结果的方式为该任务编写稳定的代码。
标签: c# multithreading thread-safety large-files