首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Net.HttpClient: SendAsync失败了,OperationCanceledException没有通过网络请求

System.Net.HttpClient: SendAsync失败了,OperationCanceledException没有通过网络请求
EN

Stack Overflow用户
提问于 2018-12-10 17:54:54
回答 2查看 9.3K关注 0票数 5

我们使用System.Net.Http.HttpClient进行k8s内部微服务之间的调用。

  • 操作系统Linux(在坞内)
  • dotnet TargetFramework: netcoreapp2.1
  • 服务器: Kestrel
  • 协议: http

几天前,我们注意到http调用非常奇怪的行为:一些微服务之间的呼叫(接近2-3%)由于错误而失败。

代码语言:javascript
复制
System.OperationCanceledException: The operation was canceled.
   at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at OurCode.HttpServiceClient.GetStringResponseAsync(String methodUri, HttpMethod httpMethod)
   ...another our code...

在超时之后,http调用(现在是3秒)。但呼叫服务内部没有通话记录。

我们为跟踪http请求启用了packet节拍,并且还注意到,没有执行从调用方服务到调用方服务的任何http请求。这个服务的CPU、内存和网络一直都很好。

我们的http调用代码的简化版本如下:

代码语言:javascript
复制
public async Task<string> GetStringResponseAsync(String methodUri,  HttpMethod httpMethod)
{
    int timeoutInMilliseconds = 3000;
    var tokenSource = new CancellationTokenSource();
    var rm = new HttpRequestMessage(httpMethod, methodUri);
    Task<HttpResponseMessage> httpTask = HttpClient.SendAsync(rm, tokenSource.Token);
    tokenSource.CancelAfter(timeoutInMilliseconds);
    HttpResponseMessage response = await httpTask;
    await EnsureSuccessStatusCode(response);
    return await response.Content.ReadAsStringAsync();
}

对于什么问题可以在没有http请求的情况下通过网络导致这种奇怪的行为,我有什么想法,我能做些什么来做进一步的调查?

EN

回答 2

Stack Overflow用户

发布于 2018-12-10 18:19:08

这只是意味着web服务没有响应。

当超时结束时,HttpClient抛出一个TaskCanceledException (从OperationCanceledException继承)。它不直观,对我(和其他人)也没有任何意义,但不幸的是,这正是它所做的。

有一些关于它的讨论,这里 (一些人提到了一些解决办法来区分超时和真正的取消,如果您关心的话)。

票数 8
EN

Stack Overflow用户

发布于 2020-12-13 21:40:55

我不知道这是否会对未来的任何人有帮助,但我也有同样的问题。原来我所在的服务器在默认情况下不是自动使用代理地址的。最后,我不得不在代码中添加以下内容:

代码语言:javascript
复制
using (var handler = new WinHttpHandler()){
       handler.WindowsProxyUsePolicy = WindowsProxyUsePolicy.UseCustomProxy;
       handler.Proxy = new WebProxy(server, port);
       //the rest of your code.....
}

这个手动添加的代理服务器信息和我的控制台应用程序开始正常工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53711104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档