HTTP 请求 PostAsync 与 HttpClient 取消请求或资源暂时不可用

Posted

技术标签:

【中文标题】HTTP 请求 PostAsync 与 HttpClient 取消请求或资源暂时不可用【英文标题】:HTTP Request PostAsync with HttpClient cancels request or Resource temporarily unavailable 【发布时间】:2021-12-30 01:23:34 【问题描述】:

关于这个问题我已经写了post。我定期发出 HTTP Get 和 Post 请求,其中一些请求返回一个错误,导致我的程序崩溃(因为没有 try-catch)。 错误来自此代码:

using (var client = new HttpClient())
            
                var response = await client.PostAsync(url, data);
                string result = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine(result);
                if (response.IsSuccessStatusCode)
                
                    Console.WriteLine("Success send post : " + result);
                 else
                
                    Console.WriteLine("Error send post");
                
            

此函数因 2 个错误而崩溃:

Unhandled Exception: System.OperationCanceledException: The operation was canceled.
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at Common.WebApi.SendHttpPost(String url, StringContent data)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__7_1(Object state)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.<>c.<.cctor>b__5_0(Object state)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:08 raspberrypi wescan[8530]: --- End of stack trace from previous location where exception was thrown ---
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.ExecuteWorkItem()
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
nov. 18 04:36:08 raspberrypi wescan[8530]:    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
nov. 18 04:36:09 raspberrypi wescan[8530]: System.OperationCanceledException: The operation was canceled.
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at Common.WebApi.SendHttpPost(String url, StringContent data)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__7_1(Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.<>c.<.cctor>b__5_0(Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]: --- End of stack trace from previous location where exception was thrown ---
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.ExecuteWorkItem()
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
nov. 18 04:36:09 raspberrypi wescan[8530]: System.OperationCanceledException: The operation was canceled.
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at Common.WebApi.SendHttpPost(String url, StringContent data)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__7_1(Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.<>c.<.cctor>b__5_0(Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]: --- End of stack trace from previous location where exception was thrown ---
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.ExecuteWorkItem()
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
nov. 18 04:36:09 raspberrypi wescan[8530]:    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

2

Unhandled Exception: System.Net.Http.HttpRequestException: Resource temporarily unavailable ---> System.Net.Sockets.SocketException: Resource temporarily unavailable
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
nov. 19 04:00:51 raspberrypi wescan[14169]:    --- End of inner exception stack trace ---
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.Tasks.ValueTask`1.get_Result()
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.Tasks.ValueTask`1.get_Result()
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.Tasks.ValueTask`1.get_Result()
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at Common.WebApi.SendHttpPost(String url, StringContent data)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__7_1(Object state)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.<>c.<.cctor>b__5_0(Object state)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 19 04:00:51 raspberrypi wescan[14169]: --- End of stack trace from previous location where exception was thrown ---
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.QueueUserWorkItemCallbackDefaultContext.ExecuteWorkItem()
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
nov. 19 04:00:51 raspberrypi wescan[14169]:    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

我发现有人告诉我将response.Content.ReadAsStringAsync().Result; 更改为response.Content.ReadAsStringAsync().GetAwaiter().GetResult();,但我暂时无法对其进行测试。 如果有人遇到过这种随机生成的错误,我很感兴趣!赛亚

【问题讨论】:

【参考方案1】:

这两个错误看起来都与连接/网络相关的错误。 可能会暂时失去与端点的连接。 这可能是因为您发送到许多请求并受到限制。

您没有说明为什么不将调用包装在 try/catch 中,而只是处理异常。我建议这样做以使代码更健壮。

【讨论】:

是的,我认为这也是网络问题,但我不知道如何检查。如果发生这种情况,我不会使用 try-catch 自愿停止我的程序,因为发送失败对我来说至关重要。 我明白了。我仍然认为异常处理是要走的路。例如,捕获特定的异常,记录它,等待 x 秒并重试,然后在 3 次重试后,然后做任何你想做的事情,即关闭应用程序等。网络连接错误发生,我认为最好让代码对此有弹性。

以上是关于HTTP 请求 PostAsync 与 HttpClient 取消请求或资源暂时不可用的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient.PostAsync 用于上传文件

Golang的一个简单实用的http客户端库httpc

对象在 PostAsync 与 HttpClient 之后被释放

HTTP PostAsync 不返回任何内容

yaws 因 httpc 崩溃:请求 docker 容器提供的 URL

为啥 HttpClient.PostAsync 似乎将请求作为 GET 而不是 POST 发送?