【问题标题】:Dynamically changing HttpClient.Timeout in .NET在 .NET 中动态更改 HttpClient.Timeout
【发布时间】:2014-07-10 13:12:42
【问题描述】:

我需要在 HttpClient.Timeout 发出请求后更改它的属性。当我尝试时,我得到一个异常:

此实例已启动一个或多个请求。只能在发送第一个请求之前修改属性。

有什么办法可以避免这种情况吗?

【问题讨论】:

  • 信息不清楚吗?
  • 在请求之前设置??
  • @L.B.,消息很清楚。但我仍然想知道是否有任何技巧可以避免这种情况。 geedubb,我需要改变。
  • @ValeO Timeout 的值用于在异步任务启动之前(内部)在CancellationTokenSource 上设置CancelAfter。所以,即使你以后可以通过一些“技巧”来改变它,它也没有任何效果。
  • @Ryan Emerle,有用的评论,谢谢。

标签: c# .net timeout dotnet-httpclient


【解决方案1】:

您无能为力来改变这一点。这只是 HttpClient 实现中的默认行为。

必须在调用 GetRequestStream 或 GetResponse 方法之前设置 Timeout 属性。 From HttpClient.Timeout Remark Section

为了更改超时,最好创建一个新的 HttpClient 实例。

client = new HttpClient();
client.Timeout = 20; //set new timeout

【讨论】:

【解决方案2】:

在内部,Timeout 属性用于设置 CancellationTokenSource,当达到超时时,它将中止异步操作。由于HttpClient 方法的一些重载接受CancellationTokens,我们可以创建帮助方法来为特定操作自定义超时:

public async Task<string> GetStringAsync(string requestUri, TimeSpan timeout)
{
    using (var cts = new CancellationTokenSource(timeout))
    {
        HttpResponseMessage response = await _httpClient.GetAsync(requestUri, cts.Token)
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsStringAsync();
    }
}

【讨论】:

  • 值得注意的是,在 HttpClient 上设置的任何超时仍将被强制执行。这只能减少请求超时所需的时间;它不能增加它。
【解决方案3】:

在我看来,缺乏对自定义请求级超时的支持一直是HttpClient 的缺点。如果你不介意小库依赖,Flurl.Http [免责声明:我是作者] 直接支持这个:

"http://api.com/endpoint".WithTimeout(30).GetJsonAsync<T>();

这是一个真正的请求级设置;对同一主机的所有调用都在后台使用共享的HttpClient 实例,并且具有不同超时的并发调用不会发生冲突。有一个可配置的全局默认值(最初为 100 秒,与 HttpClient 相同)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2014-07-17
    • 2021-01-19
    • 2017-12-03
    相关资源
    最近更新 更多