您无法加快速度,因为瓶颈是您的 Internet 连接。但是,您可以做一些事情:
1)不要 LINQ 计算行数,它是一个数组,它的大小是已知的(微优化,你永远不会注意到这种变化)。
2)using
用于释放一次性对象(与速度无关,更好的错误处理:如果您的代码出现问题,您将使用 GC 释放资源)。
3)使它们平行。这将加快速度:
private void button4_Click(object sender, EventArgs e)
{
var lines = File.ReadAllLines(@"c:\data\temp.txt");
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(lines, options, line =>
{
var request = WebRequest.Create(line);
using (var response = request.GetResponse())
{
var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII);
// Do your stuff
BeginInvoke(new MethodInvoker(delegate
{
textBox1.Text += ".";
}));
}
});
}
还有一些注意事项:
为了使其成为更完整的示例,您的点击事件处理程序将是:
private void button4_Click(object sender, EventArgs e)
{
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(ReadUrlList(@"c:\data\temp.txt"), options, ProcessUrl);
}
处理每个 URL 和读取 URL 列表的实际代码:
private static string[] ReadUrlList(string path)
{
return File.ReadAllLines(@"c:\data\temp.txt");
}
private void ProcessUrl(string url)
{
ProcessResponse(response =>
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
// Do your stuff
// We're working on separate threads, to access UI we
// have to dispatch the call to UI thread. Note that
// code will be executed asynchronously then local
// objects may have been disposed!
BeginInvoke(new MethodInvoker(delegate
{
textBox1.Text += ".";
}));
}
});
}
使用此辅助方法隐藏网络操作的尝试/等待模式:
private static void ProcessResponse(string url, Action<WebResponse> action)
{
for (int i=1; i <= NumberOfRetries; ++i)
{
try
{
var request = WebRequest.Create(line);
using (var response = request.GetResponse())
{
action(response);
}
break;
}
catch (Exception e)
{
if (i == NumberOfRetries)
throw;
Thread.Sleep(DelayOnRetry);
}
}
}
private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;