WebClient 将非2xx状态码视为异常直接抛出WebException,而HttpClient仅在网络错误时抛HttpRequestException,正常HTTP错误需手动检查StatusCode。

WebClient 一调就报 WebException,HttpClient 却不抛异常?
这是最常踩的坑:用 WebClient 请求一个返回 404 或 500 的 API,代码直接崩在 DownloadString 上,抛出 WebException;而换成 HttpClient,GetAsync 照常返回 HttpResponseMessage,得手动检查 response.IsSuccessStatusCode 才知道失败了。
-
WebClient把所有非 2xx 状态码当“异常”处理(哪怕 404 是你预期的业务结果) -
HttpClient只在真正出问题时才抛HttpRequestException(比如 DNS 失败、连接超时、服务器完全不可达) - 这意味着:用
WebClient你得 try-catch 每次调用;用HttpClient你可以统一判断StatusCode,再分情况处理(如 401 跳登录、404 提示资源不存在)
为什么 new HttpClient() 用几次就卡死或报 SocketException?
这不是 bug,是误用。很多人照着示例写 using (var client = new HttpClient()),结果高并发下出现 SocketException: Only one usage of each socket address is normally permitted。
-
HttpClient设计为**长生命周期复用**,不是一次性的 —— 它背后维护 TCP 连接池 - 每次
new HttpClient()都新建连接池,频繁创建销毁会快速耗尽本地端口(TIME_WAIT 状态堆积) -
WebClient虽也有类似风险,但因默认同步+低并发场景多,问题不明显;而HttpClient异步高频使用时立刻暴露 - 正确做法:全局单例、DI 注入
IHttpClientFactory,或至少在类级别复用实例
上传文件、下载大文件,该选哪个?
看需求粒度。如果只是“把本地文件发到某个 URL”,WebClient.UploadFile 一行搞定;但如果要监控进度、设超时、加 token、支持断点续传、或上传流式数据(比如压缩中上传),HttpClient 是唯一选择。
2013年07月06日 V1.60 升级包更新方式:admin文件夹改成你后台目录名,然后补丁包里的所有文件覆盖进去。1.[新增]后台引导页加入非IE浏览器提示,后台部分功能在非IE浏览器下可能没法使用2.[改进]淘客商品管理 首页 列表页 内容页 的下拉项加入颜色来区别不同项3.[改进]后台新增/修改淘客商品,增加淘宝字样的图标和天猫字样图标改成天猫logo图标4.[改进]为统一名称,“分类”改
-
WebClient:只支持完整文件路径上传,不支持Stream或分块;无进度回调;不能设Timeout(只能靠底层WebRequest默认值) -
HttpClient:可传StreamContent、设client.Timeout = TimeSpan.FromSeconds(60)、用Progress监听上传进度、支持CancelToken中断 - 注意:
WebClient的UploadFileAsync声称异步,但底层仍是同步 I/O 封装,无法真正释放线程;HttpClient的异步才是真正的 awaitable I/O
新项目里还能用 WebClient 吗?
能,但不建议。.NET 官方已将 WebClient 标记为 [Obsolete](https://learn.microsoft.com/en-us/do.net/api/system.net.webclient?view=net-8.0#remarks)(自 .NET 6 起警告,.NET 8+ 默认启用警告)。
- 它不支持 HTTP/2、不支持请求拦截器、不能配置消息处理器链(比如自动加 Auth Header)、无法集成 Polly 重试
- 所有现代库(如 Refit、Flurl)都基于
HttpClient构建;第三方认证库(Microsoft.Identity.Web)也只提供HttpClient扩展 - 例外场景:写个临时控制台工具快速抓网页内容,
new WebClient().DownloadString(url)确实快——但这种“快”是以牺牲可维护性和未来扩展性换来的
真正容易被忽略的点是:异常语义差异不是风格偏好,而是设计契约。把 404 当异常捕获,等于把“资源不存在”当成程序错误;而把它作为正常响应处理,才能写出可预测、可观测、易测试的 HTTP 客户端逻辑。









