我正在对已经编写的一些旧代码进行自我审查,并想知道以下代码段是否以任何方式阻塞了当前线程,还是一直阻塞着?
按照Microsoft的建议,我对所有应用程序使用单个HttpClient实例
HttpClient旨在实例化一次,并在应用程序的整个生命周期内重复使用。为每个请求实例化HttpClient类将耗尽繁重负载下可用的套接字数量。这将导致SocketException错误。https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.8#remarks
public virtual async Task<Tuple<string, bool>> PostAsync(string resourceUrl, string body, string basicToken)
{
string methodName = "PostAsync";
var response = new Tuple<string, bool>(string.Empty, false);
try
{
var content = new StringContent(body, Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Post, resourceUrl);
request.Headers.Add("Authorization", basicToken);
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var httpResponse = await ApplicationWrapper.AccessTokenClient.SendAsync(request).ConfigureAwait(false);
response = new Tuple<string, bool>(await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), httpResponse.IsSuccessStatusCode);
}
catch (WebException e)
{
Util.Log(methodName + " | WebException: " + e.Message + "|" + e.StackTrace.ToString());
using (WebResponse WebResponse = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)WebResponse;
using (var streamReader = new StreamReader(WebResponse.GetResponseStream()))
Util.Log(methodName + " | Exception postAsync API: " + streamReader.ReadToEnd());
}
}
catch (Exception ex)
{
Util.Log(methodName + " | Exception: " + ex.Message + "|" + ex.StackTrace.ToString() + "|" + ex.InnerException);
}
return response;
}
Microsoft对ReadAsStringAsync声明的事实
此外,为了避免死锁,建议使用ConfigureAwait(false)
ConfigureAwait(false)配置任务,以便不必在调用方上下文中运行等待之后继续执行,因此避免了任何可能的死锁。 https://medium.com/bynder-tech/c-why-you-should-use-configureawait-false-in-your-library-code-d7837dce3d7f
由于压力不断增加,阻塞的异步代码可能会影响服务器,CPU使用率达到90%。 上面的代码中是否有任何方面被阻止?
答案 0 :(得分:4)
这一切对我来说都很好。一个简单的经验法则是,如果您在异步方法的返回值(.Result
)上看到.Wait()
或Task
的任何出现,则表示您在可能< / em>应该await
。在这里看不到-您似乎正在等待所有异步调用。现在,只需确保此方法的所有 calling 都await
,并且一直到调用堆栈。如果您在任何地方都堵住了,那一切都是徒劳的。 :)