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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:52:24