为何WebClient的DownloadProgressChanged事件未触发?
WebClient异步下载时DownloadProgressChanged事件不触发的问题解决
使用WebClient进行异步文件下载时,已绑定DownloadProgressChanged与DownloadFileCompleted事件,DownloadFileCompleted可正常触发,但DownloadProgressChanged始终未触发。相关代码如下:
public void DownloadFile(string urlAddress, string location) { Stopwatch sw = new Stopwatch(); using (WebClient webClient = new WebClient()) { webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome"); webClient.DownloadFileCompleted += new AsyncCompletedEventHandler((sender, e) => Completed(sender, e, sw)); webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, sw)); Uri URL = new Uri(urlAddress); sw.Start(); try { webClient.DownloadFileAsync(URL, location); } catch (Exception ex) { MessageBox.Show(ex.Message); } } }
ProgressChanged事件定义:
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Stopwatch sw) { string itsnevergettinghereusingabreakpoint = ""; }
问题原因分析
- WebClient对象被提前释放:代码中用
using块包裹WebClient,DownloadFileAsync是异步方法,方法执行到using块末尾时会立即释放WebClient对象,导致进度事件因对象已回收而无法触发,这是当前代码的核心问题。 - 服务器未返回Content-Length响应头:
DownloadProgressChanged事件依赖服务器返回的文件总大小计算进度,若服务器未提供该响应头,WebClient无法计算进度百分比,也就不会触发事件。 - 文件过小下载过快:如果目标文件体积极小,异步下载瞬间完成,进度事件可能来不及触发就直接进入完成阶段。
解决方案
- 手动管理WebClient生命周期:移除
using块,在DownloadFileCompleted事件中手动释放WebClient,同时在异常分支也确保对象被释放:
public void DownloadFile(string urlAddress, string location) { Stopwatch sw = new Stopwatch(); WebClient webClient = new WebClient(); webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome"); webClient.DownloadFileCompleted += (sender, e) => { Completed(sender, e, sw); webClient.Dispose(); }; webClient.DownloadProgressChanged += (sender, e) => ProgressChanged(sender, e, sw); Uri URL = new Uri(urlAddress); sw.Start(); try { webClient.DownloadFileAsync(URL, location); } catch (Exception ex) { MessageBox.Show(ex.Message); webClient.Dispose(); } }
- 验证服务器响应头:通过浏览器开发者工具的网络面板,查看下载请求的响应头是否包含
Content-Length字段。若缺失,需协调后端配置返回该字段,或改为仅跟踪已下载字节数(无法计算百分比)。 - 测试大文件下载:换用体积较大的文件进行测试,排除因下载速度过快导致进度事件未触发的情况。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

