Unity中C# HttpClient请求超时无法立即取消任务的问题
Unity中HttpClient异步请求超时不生效的解决方案
1. 切换Unity的.NET运行时版本
Unity默认的旧版.NET兼容模式(如.NET Framework 3.5)对HttpClient的超时逻辑支持不完善,先修改项目设置:
- 打开
PlayerSettings->Other Settings->Configuration - 将
Scripting Runtime Version设置为.NET 4.x Equivalent或更高版本 - 重启Unity使设置生效
2. 手动实现超时竞争逻辑
由于Unity异步调度特性,单独依赖HttpClient.Timeout或CancellationTokenSource可能无法立即触发超时,用Task.WhenAny让请求任务和超时任务竞争,确保超时后立即取消请求:
async Task MakeTimedRequest(string requestUrl, int timeoutSeconds) { using var cancellationTokenSource = new CancellationTokenSource(); // 创建超时任务 var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds), cancellationTokenSource.Token); // 创建请求任务 var httpRequestTask = _httpClient.GetAsync(requestUrl, cancellationTokenSource.Token); // 等待先完成的任务 var completedTask = await Task.WhenAny(httpRequestTask, timeoutTask); if (completedTask == timeoutTask) { // 超时触发,取消请求并抛出异常 cancellationTokenSource.Cancel(); throw new TaskCanceledException("请求超时"); } // 请求成功完成,处理响应 var response = await httpRequestTask; response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); // 后续业务处理 }
3. 结合Unity协程调度异步任务
Unity主线程无法直接处理纯异步方法的回调,需要将异步任务包装成协程,确保超时异常能及时捕获:
// 复用全局HttpClient实例(避免频繁创建销毁) private static HttpClient _httpClient; void Awake() { _httpClient = new HttpClient(); } IEnumerator ExecuteRequestWithTimeout(string url) { var requestTask = MakeTimedRequest(url, 3); yield return new WaitUntil(() => requestTask.IsCompleted); if (requestTask.IsFaulted) { Debug.LogError($"请求错误: {requestTask.Exception.InnerException.Message}"); } else if (requestTask.IsCanceled) { Debug.LogError("请求因超时被取消"); } else { Debug.Log("请求完成"); } } // 调用方式 void Start() { StartCoroutine(ExecuteRequestWithTimeout("http://localhost/your-api")); }
4. 注意事项
- 不要在Unity主线程中用
.Result或.Wait()阻塞异步任务,会导致主线程卡死且超时逻辑失效 - 全局HttpClient实例要注意在场景切换或游戏退出时正确释放,避免内存泄漏
内容的提问来源于stack exchange,提问作者WhyImUser_user3290746
相关产品推荐
相关产品推荐

