C# HttpClient Polly超时策略
get请求等待的时间比超时的C# HttpClient Polly超时策略,c#,timeout,httpclient,polly,C#,Timeout,Httpclient,Polly,get请求等待的时间比超时的timeoutPolicy长 有人知道为什么会这样吗 为什么请求没有在30毫秒时超时 var-timeoutPolicy=Policy.TimeoutAsync(TimeSpan.frommicles(30),TimeoutStrategy.optimized); var watch=新秒表(); 尝试 { watch.Start(); var httpResponse=await timeoutPolicy.ExecuteAsync( async ct=>等待h
timeoutPolicy
长
- 有人知道为什么会这样吗
- 为什么请求没有在30毫秒时超时
var-timeoutPolicy=Policy.TimeoutAsync(TimeSpan.frommicles(30),TimeoutStrategy.optimized);
var watch=新秒表();
尝试
{
watch.Start();
var httpResponse=await timeoutPolicy.ExecuteAsync(
async ct=>等待httpClient.SendAsync(新的HttpRequestMessage(HttpMethod.Get)https://google.com(华盛顿州),,
取消令牌。无
);
看,停;
Console.WriteLine(“请求耗时”+watch.ElapsedMilliseconds);
}
捕获(例外e)
{
看,停;
Console.WriteLine(“超时时间”+watch.ElapsedMilliseconds);
控制台写入线(e.Message);
}
我想我已经玩够了,我知道发生了什么,所以我有信心现在可以回答这个问题
当您使用TimeoutStrategy.optimize
Polly策略调用async
任务时,您传递的是CancellationToken
,基本上相信将调用CancellationToken
以在超时场景中结束任务
与TimeoutStrategy.Pesimistic
策略的行为不同,该策略旨在终止不通过CancellationToken
回调的同步任务
虽然主执行线程没有被另一个线程上运行的异步任务阻塞,但重要的是要记住,该任务确实能够阻塞自己的线程
例如,如果一个异步任务调用Thread.Sleep(1000)
,那么它的线程将被阻塞一秒钟。这反过来意味着在块期间不能调用CancellationToken
在这种情况下,我相信长时间运行的操作(例如第一次查找DNS记录中的主机名)或任何其他阻塞操作正在发生,这些操作实际上会阻塞线程90毫秒
因此,即使任务知道它需要在30毫秒时中止,它也需要等待线程可用,然后才能真正调用取消,直到大约90毫秒左右才会发生
返回超时的延迟似乎只在每个域解析的第一次出现,因此我认为这与名称服务器缓存和DNS解析有关,因为后续调用似乎更有效地执行超时。尽管断言任何直接的根本原因在很大程度上都是推测。它看起来像是
TimeoutStrategy。乐观的需要使用CancellationToken
,否则如果您不能信任CancellationToken
,那么它将与TimeoutStrategy.悲观的一起工作。尝试将CancellationToken
传递给SendAsync
取消令牌,即ct传递给SendAsync。它确实会引发超时异常,但引发超时异常的时间超过30毫秒,大约90毫秒。我怀疑传入的CancellationToken
实际上就是您接下来指定的CancellationToken。无。不过我不完全确定。我的测试都是用任意的Task.Run()
完成的,测试时不会取消。所以这可能是一个不同的场景,我没有正确地复制它。如果你得到了超时,但有点延迟,也许Polly没有你想要的那么精确,尽管这表明我在这个主题上显然没有期望,所以希望其他人可以帮助。我将代码一行一行复制到一个测试中,并且可以确认,在我运行这个测试的前几次,我得到了90毫秒的延迟。在那之后,我开始持续30毫秒的超时。也许还有其他一些事情出乎意料地增加了计时器。e、 g.秒表计时但线程开始执行之前,使线程旋转所需的时间。或者,即使只是垃圾收集也会在启动和停止秒表之间增加延迟。