Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HttpClient Polly超时策略_C#_Timeout_Httpclient_Polly - Fatal编程技术网

C# HttpClient Polly超时策略

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

get请求等待的时间比超时的
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.秒表计时但线程开始执行之前,使线程旋转所需的时间。或者,即使只是垃圾收集也会在启动和停止秒表之间增加延迟。