我正在创建一个使用REST API的应用程序。我把HTTP调用包装在这样的类中。这个类中有许多类似的方法。我为所有方法重用了相同的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;
}
我使用计时器定期调用API(每个计时器调用不同的API)。当只有一个计时器时,程序似乎运行良好。但是当有两个定时器时,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
内部追踪:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
外部追踪:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
请求被取消是什么意思?它与Web服务器端无关,对吧?在多个线程(Task
s)中调用HttpClient时是否需要处理某些事情?
更新
在使用HTTP分析器查看流量后,我发现同一个HTTP请求(应该一次只能进行一次)非常多。我在第三方UI控件的选择更改事件中启动了该任务。由于某种原因,当实际选择没有改变时,UI控件提高了选择更改事件的速度。我正在调查原因,如果这是原因,我可能不得不关闭这个问题。
更新2
我找到了一种方法来抑制那些冗余选择更改事件,现在不会发生异常。我试图删除这个问题,但警告说Stack Overflow不建议这样做,如果我继续这样做,我可能会被阻止Stack Overflow。关闭选项不符合真正的原因,所以我会离开这个。对将来有类似问题的人可能会有所帮助。
答案 0 :(得分:4)
您应该不调用.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;
}
此处的问题是,您要卸载第一个await
上的async (ConfigureAwait(false))
,然后在第二个.Result
上调用.Result
。我无法看到应用程序的其余部分,但您可能会在qualityChanged
电话上陷入僵局。
Stephan Cleary's: Article on why you shouldn't block on Async Code