boo*_*ife 24 .net dotnet-httpclient
为了重用开放的TCP连接,HttpClient您必须为所有请求共享一个实例.
这意味着我们不能简单地HttpClient使用不同的设置(例如超时或标头)进行实例化.
我们如何共享连接并同时使用不同的设置?这很简单,实际上是默认的,旧的HttpWebRequest和WebClient基础设施.
请注意,HttpClient.Timeout在发出请求之前简单设置不是线程安全的,并且不能在并发应用程序(例如ASP.NET网站)中工作.
Tod*_*ier 41
在引擎盖下,HttpClient只需使用取消令牌来实现超时行为.如果您想根据请求更改它,可以直接执行相同的操作:
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(30));
await httpClient.GetAsync("http://www.google.com", cts.Token);
Run Code Online (Sandbox Code Playgroud)
请注意,默认超时为HttpClient100秒,即使您在请求级别设置了更高的值,该请求仍将在该点取消.要解决此问题,请在其上设置"max"超时,该超时HttpClient可以是无限的:
httpClient.Timeout = System.Threading.Timeout.InfiniteTimeSpan;
Run Code Online (Sandbox Code Playgroud)
接受的答案很好,但我想为将来寻找这个的人提供另一种情况。就我而言,我已经在使用 CancellationTokenSource ,它会在用户选择取消时取消其令牌。因此,在这种情况下,您仍然可以通过使用 CancellationTokenSource 的 CreateLinkedTokenSource 方法来使用此技术。因此,在我的场景中,http 操作将因超时或用户干预而取消。这是一个示例:
public async static Task<HttpResponseMessage> SendRequest(CancellationToken cancellationToken)
{
var ctsForTimeout = new CancellationTokenSource();
ctsForTimeout.CancelAfter(TimeSpan.FromSeconds(5));
var cancellationTokenForTimeout = ctsForTimeout.Token;
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTokenForTimeout))
{
try
{
return await httpClient.GetAsync("http://asdfadsf", linkedCts.Token);
}
catch
{
//just for illustration purposes
if (cancellationTokenForTimeout.IsCancellationRequested)
{
Console.WriteLine("timeout");
}
else if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("other cancellation token cancelled");
}
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)