You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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无法计算进度百分比,也就不会触发事件。
  • 文件过小下载过快:如果目标文件体积极小,异步下载瞬间完成,进度事件可能来不及触发就直接进入完成阶段。

解决方案

  1. 手动管理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();
    }
}
  1. 验证服务器响应头:通过浏览器开发者工具的网络面板,查看下载请求的响应头是否包含Content-Length字段。若缺失,需协调后端配置返回该字段,或改为仅跟踪已下载字节数(无法计算百分比)。
  2. 测试大文件下载:换用体积较大的文件进行测试,排除因下载速度过快导致进度事件未触发的情况。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:48:23