我有一个WinForms应用程序,每天需要下载很多(数万个)相当大(多MB)的文件。我使用以下代码编写了一个简单的测试:
using (var wc = new System.Net.WebClient())
{
foreach (string url in UrlsToDownload())
{
string targetPath = SafeFilePathOf(url);
wc.DownloadFile(url, targetPath);
}
}
目标计算机具有1 Gb / s连接,但测试显示持续下载大约1MB / s。这比我预期的要少,但源服务器可能连接速度较慢。一整天的下载需要几个小时的连接,这是可以接受的。网络利用率相当稳定在1%左右:
但是,我需要在后台线程中执行下载并支持取消和下载进度。 .Net
System.ComponentModel.BackgroundWorker
似乎是为此设计的,因此我将完全相同的代码放在BackgroundWorker
实例中并调用RunWorkerAsync
:
下载性能直线下降到约0.05 MB / s。一天的工作需要大约一个星期的时间来完成;这不会飞。
为什么BackgroundWorker
表现如此糟糕? CPU和网络都没有过载。应用程序未被阻止,我只是将下载代码从UI线程移动到BackgroundWorker
。致电backgroundWorker.Priority = ThreadPriority.AboveNormal
无效。
答案 0 :(得分:0)
无论是后台线程还是UI线程,网络活动都会执行相同的操作。问题可能是报告进度或日志记录活动等的任何其他代码。这可能会阻止该线程。
答案 1 :(得分:0)
增加WebClient上的连接限制:
internal class CustomWebClient : WebClient
{
public CustomWebClient()
{
}
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest w = (HttpWebRequest)base.GetWebRequest(uri);
w.ServicePoint.ConnectionLimit = 100;
return w;
}
}