同步HttpWebRequest断网后卡住无返回,因递归无法异步求取消方法
解决同步HttpWebRequest断网后卡住的问题
不需要改用异步方案,你可以通过以下两种方式结合来取消卡住的请求:
1. 设置请求超时(Timeout)
给HttpWebRequest设置Timeout属性,当请求超过指定时间未完成时,会自动抛出WebException,避免无限卡住。这个属性控制整个请求的超时时间(包括连接和响应读取),单位为毫秒。
修改后的DoWork示例:
private void DoWork() { HttpWebRequest httpWebRequest = null; try { httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); httpWebRequest.Method = WebRequestMethods.Http.Get; httpWebRequest.Timeout = 30000; // 设置30秒超时 using (var response = (HttpWebResponse)httpWebRequest.GetResponse()) { // 处理响应逻辑 ... } } catch (WebException ex) { if (ex.Status == WebExceptionStatus.Timeout) { // 处理超时情况,比如重试或终止流程 } // 其他异常处理 } }
2. 监听网络状态并主动终止请求
通过NetworkChange类监听系统网络可用性变化,当检测到网络断开时,调用HttpWebRequest.Abort()方法主动终止请求,此时GetResponse()会立即抛出WebException(状态为WebExceptionStatus.RequestCanceled)。
步骤:
- 注册网络状态变化事件
- 在事件回调中终止当前请求
示例代码:
// 类级别的字段,保存当前正在执行的请求 private HttpWebRequest _currentRequest; // 初始化时注册网络事件 public YourClassConstructor() { NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged; } private void DoWork() { try { _currentRequest = (HttpWebRequest)WebRequest.Create(uri); _currentRequest.Method = WebRequestMethods.Http.Get; _currentRequest.Timeout = 30000; using (var response = (HttpWebResponse)_currentRequest.GetResponse()) { // 处理响应 ... } } catch (WebException ex) { if (ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.RequestCanceled) { // 处理超时或主动取消的情况 } // 其他异常处理 } finally { _currentRequest = null; // 清空请求引用 } } // 网络状态变化回调 private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { // 网络断开且存在未完成的请求时,主动终止 if (!e.IsAvailable && _currentRequest != null) { _currentRequest.Abort(); } }
注意事项
NetworkChange事件依赖系统网络通知,部分环境下可能存在延迟,因此搭配Timeout可以双重保障。Abort()方法是线程安全的,可以在非请求线程中调用。- 处理
WebException时,通过Status属性区分超时、主动取消等不同场景,针对性处理逻辑。
内容的提问来源于stack exchange,提问作者Action Heinz
相关产品推荐
相关产品推荐

