WebClient.DownloadFile 在BackgroundWorker 性能不可接受
我有一个 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% 左右:
However, I need to perform downloads in a background thread and support cancelling and download progress. The .NetSystem.ComponentModel.BackgroundWorker
seems designed for this, so I put the exact same code in a BackgroundWorker
instance and call RunWorkerAsync
: 下载性能骤降至约 0.05 MB/s。一天的工作大约需要一周的时间才能完成;这不会飞。
为什么 BackgroundWorker
性能如此糟糕? CPU和网络都没有过载。应用程序没有被阻止,我只是将下载代码从 UI 线程移至 BackgroundWorker
。调用backgroundWorker.Priority = ThreadPriority.AboveNormal 没有任何效果。
I have a WinForms application that needs to download many (tens of thousands) fairly large (multi-MB) files per day. I wrote a simple test using the following code:
using (var wc = new System.Net.WebClient())
{
foreach (string url in UrlsToDownload())
{
string targetPath = SafeFilePathOf(url);
wc.DownloadFile(url, targetPath);
}
}
The target machine has a 1 Gb/s connection, but testing shows a sustained download of about 1MB/s. This is less than what I was expecting, but the source servers may have slower connections. A full day's download will require several hours of connectivity, which is acceptable. Network utilization is fairly constant at about 1%:
However, I need to perform downloads in a background thread and support cancelling and download progress. The .Net System.ComponentModel.BackgroundWorker
seems designed for this, so I put the exact same code in a BackgroundWorker
instance and call RunWorkerAsync
:
Download performance plummets to about 0.05 MB/s. A day's work will require about a week to perform; this is not going to fly.
Why is BackgroundWorker
performance so bad? Neither the CPU nor network is overloaded. The application is not blocked, I simply moved the download code from the UI thread to a BackgroundWorker
. Calling backgroundWorker.Priority = ThreadPriority.AboveNormal
has no effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
增加 WebClient 上的连接限制:
Increase the connection limit on the WebClient:
无论是后台线程还是 UI 线程,网络活动都会执行相同的操作。问题可能是报告进度或记录活动等的任何其他代码。这可能会阻塞线程。
Network activity performs same whether it's background thread or UI thread. The problem can be any other code of reporting progress or logging activity etc. That may block the thread.