webclient.downloadfile 会阻塞线程,ui 线程调用将导致界面卡死;应改用 downloadfileasync 或 task.run 包裹,认证需手动设 credentials 或 authorization header,大文件下载需节流进度更新,新项目应优先使用 httpclient。

WebClient.DownloadFile 会阻塞线程,别在 UI 线程直接调用
直接在 WinForms 或 WPF 的按钮点击事件里写 webClient.DownloadFile(url, path),界面会卡死。这不是 bug,是同步下载的必然行为。它会一直等到文件写完才返回,期间整个线程挂起。
实操建议:
- 用
DownloadFileAsync替代 —— 它不阻塞,但需监听DownloadProgressChanged和DownloadFileCompleted事件来更新进度和处理完成逻辑 - 如果必须同步(比如控制台工具),至少用
Task.Run(() => webClient.DownloadFile(...))包一层,避免污染主线程 - 注意:
DownloadFileAsync不支持取消,如需取消请改用HttpClient+GetStreamAsync
WebClient.DownloadFile 报“远程服务器返回错误: (401) 未授权”
常见于需要认证的接口或私有 CDN 资源。WebClient 默认不带任何凭据,服务端直接拒掉。
实操建议:
- 设置
webClient.Credentials = CredentialCache.DefaultCredentials(适用于 Windows 集成认证) - 对 Basic Auth,手动加 Header:
webClient.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("user:pass")) - 对 Bearer Token:
webClient.Headers[HttpRequestHeader.Authorization] = "Bearer your-token-here" - 某些服务(如 GitHub API)还要求
User-Agent,漏掉也会 403:webClient.Headers[HttpRequestHeader.UserAgent] = "MyApp/1.0"
大文件下载时进度不准、回调频率高、内存暴涨
DownloadProgressChanged 事件默认每 1KB 触发一次,下载 1GB 文件就会触发百万次事件,UI 更新压力大,且内部缓冲策略可能导致 reported progress 跳变(比如从 23% 直跳到 57%)。
6款图片鼠标悬停效果JS代码,鼠标悬停在图片上后,文字标题以6种不同的动画形式出现,兼容主流浏览器,php中文网推荐下载! 使用方法: 1、head区域引用css文件,modernizr.custom.js 2、在文件中加入!-- 代码 开始 --!-- 代码 结束 --区域代码 3、复制images文件夹里的图片到相应的路径
实操建议:
- 用
Threading.Timer或DispatcherTimer做节流,在 UI 线程中每 200–500ms 更新一次进度条,而不是每次事件都更新 - 检查
e.ProgressPercentage是否为 -1(表示无法获取总大小),此时应改用e.BytesReceived和预估总长做计算,别硬绑进度条 Value - 避免在事件里做耗时操作(如写日志到磁盘、JSON 序列化),否则拖慢整个下载流程
WebClient 已过时,新项目优先用 HttpClient
.NET Core 2.1+ 和 .NET 5+ 中,WebClient 被标记为“遗留类型”,官方文档明确建议迁移到 HttpClient。它更轻量、支持取消、可复用、配合 async/await 更自然。
实操建议:
- 用
httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)获取响应头,再用response.Content.ReadAsStreamAsync()流式读取,边下边写到FileStream - 务必使用
using var stream = await response.Content.ReadAsStreamAsync(),防止连接泄漏 - 取消下载只需传入
cancellationToken到GetAsync和后续读取中,无需自己管理状态
WebClient 看似简单,但异常处理、超时控制、重试、Cookie 管理这些实际需求一上来,代码很快变得臃肿。HttpClient 虽然初看多几行,但边界清晰、可控性强——尤其当你需要支持断点续传或自定义 DNS 解析时,WebClient 几乎没法扩展。









