简体   繁体   English

在多个任务中访问HttpClient会导致“请求被取消”异常

[英]Accessing HttpClient in multiple tasks causes “The request was canceled” exceptions

I am creating an application that consumes REST API's. 我正在创建一个使用REST API的应用程序。 I wrapped the HTTP calls in a class like this. 我把HTTP调用包装在这样的类中。 There are many similar methods in this class. 这个类中有许多类似的方法。 I reuse the same HttpClient instance for all methods, as StackOverflow answers said it was meant to be reused and designed thread-safe. 我为所有方法重用了相同的HttpClient实例,因为StackOverflow的答案表示它意味着可以重用并设计为线程安全的。

public async Task<DataType> GetData()
{
    var address = "XXX";
    var res = await Client.GetAsync(address).ConfigureAwait(false);
    var data = res.Content.ReadAsStringAsync().Result;
    return data;
}

I use timers to call API's regularly (each timer calls a different API). 我使用计时器定期调用API(每个计时器调用不同的API)。 When there is only one timer, the programme seems to run well. 当只有一个计时器时,程序似乎运行良好。 But when there are two timers, System.Net.Http.HttpRequestException keeps happening at the second line. 但是当有两个定时器时, System.Net.Http.HttpRequestException会在第二行继续发生。

System.Net.Http.HttpRequestException: 'An error occurred while sending the request.'
Inner Exception
WebException: The request was aborted: The request was canceled

Inner trace: 内部痕迹:

at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)

Outer trace: 外部痕迹:

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()

What does it mean the request was cancelled? 请求被取消是什么意思? It is not related to the web server side, right? 它与Web服务器端无关,对吧? Do I need to take care of something when calling HttpClient in multiple threads ( Task s)? 在多线程中调用HttpClient时是否需要处理某些事情( Task )?

Update 更新

After seeing the traffic with an HTTP analyser, I found that the same HTTP requests (which supposed to be made only once at a time) were made very many at once. 在使用HTTP分析器查看流量后,我发现同一个HTTP请求(应该一次只能进行一次)非常多。 I started the task at a selection changed event of a third-party UI control. 我在第三方UI控件的选择更改事件中启动了该任务。 And for some reason, the UI control raised selection changed events very quickly when actually the selection was not changed. 由于某种原因,当实际选择没有改变时,UI控件提高了选择更改事件的速度。 I am investigating the cause, and if that is the reason, I may have to close this question. 我正在调查原因,如果是这个原因,我可能不得不关闭这个问题。

Update 2 更新2

I found out a way to suppress those redundant selection changed events and now the exception does not occur. 我找到了一种方法来抑制那些冗余选择更改事件,现在不会发生异常。 I tried to delete the question, but the warning said that Stack Overflow did not recommend doing so, and if I kept doing it, I might be blocked from Stack Overflow. 我试图删除这个问题,但警告说Stack Overflow不建议这样做,如果我继续这样做,我可能会被阻止Stack Overflow。 Closing options did not fit the real reason, so I will leave this. 关闭选项不符合真正的原因,所以我会离开这个。 It might be helpful to someone with similar problems in the future. 它可能对将来遇到类似问题的人有所帮助。

You should not call the .Result instead 应该调用.Result ,而不是

public async Task<DataType> GetData()
{
    var address = "XXX";
    var res = await Client.GetAsync(address).ConfigureAwait(false);
    var data = await res.Content.ReadAsStringAsync().ConfigureAwait(false);
    return data;
}

The issue here is you are offloading the await on the first async (ConfigureAwait(false)) but then calling .Result on the second. 这里的问题是你在第一个async (ConfigureAwait(false))上卸载await ,然后在第二个上调用.Result I can't tell without seeing the rest of the application but you maybe deadlocking on the .Result call. 我没有看到应用程序的其余部分,但你可能在.Result调用上死锁。

Stephan Cleary's : Article on why you shouldn't block on Async Code Stephan Cleary :关于为什么不应该阻止异步代码的文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 HttpClient - 请求已取消 - 超时 100 秒 - HttpClient - Request was canceled - Timeout of 100 seconds elapsing 当 iOS 应用程序处于后台时,HttpClient Web 服务请求被取消 - HttpClient web service request gets canceled when iOS app is backgrounded WebException的根本原因是什么,消息“请求已中止:请求已取消。” - What are the underlying causes of a WebException with message “The request was aborted: The request was canceled.” 从多个任务访问画布 - Accessing Canvas from Multiple Tasks 处理来自异步并行任务的多个异常 - Handling multiple exceptions from async parallel tasks 由于将日志添加到 Log Analytics 时配置的 HttpClient.Timeout 已超过 100 秒,请求被取消 - The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing on adding logs to Log Analytics 请求被中止:请求被取消 - The request was aborted: The request was canceled 处理在已取消的任务中引发的异常 - Handling exceptions thrown in a canceled Task HttpClient 解码我编码的 URI 导致请求失败 - HttpClient decoding my encoded URI causes request to fail 从多个任务访问相同的文件 - Accessing the same files from multiple tasks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM