【问题标题】:How to avoid deadlocks when calling an async method synchronously using HttpClient使用 HttpClient 同步调用异步方法时如何避免死锁
【发布时间】:2026-02-07 03:30:01
【问题描述】:

我必须通过 C# 方法对 Web api 进行 POST 调用。此方法不能是返回任务的异步。它必须是同步方法。以下是我的代码示例。标记为“当前代码 - 工作”的部分实际上正在工作。因为它可能会导致死锁,如https://docs.microsoft.com/en-us/archive/blogs/jpsanders/asp-net-do-not-use-task-result-in-main-context 所述,我想按照文章中的说明进行更改。修改后的方法在“修改代码”下给出。问题是它返回 400, Bad Request 错误。

//Current code - working
public HttpResponseMessage SendData(String jsonData)       
{
    HttpClient client = new HttpClient();
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;

    HttpResponseMessage resp = client.PostAsync(uri, new StringContent(jsonData, Encoding.UTF8, "application/json")).Result;

    if (resp.IsSuccessStatusCode)
    {
        //code to handle success
    }
    else
    {
        //code to handle error
    }
}

//Modified code. Returns 400, bad request
private static HttpResponseMessage SendData(string jsonData)
{
    HttpClient client = new HttpClient();
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;

    Task<HttpResponseMessage> callTask = Task.Run(() => client.PostAsync(uri, new StringContent(jsonData, Encoding.UTF8, "application/json")));
    callTask.Wait();

    HttpResponseMessage response = callTask.Result;
    return response;
}

【问题讨论】:

  • 你的目标是什么运行时?

标签: asp.net asp.net-web-api async-await httpclient


【解决方案1】:

基本上,您可以使用.GetAwaiter().GetResult() 同步获取异步操作的结果。例如

private static HttpResponseMessage SendData(string jsonData)
{
    // HttpClient is intended to be instantiated once per application, rather than per-use. See 
    // https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.1
    HttpClient client = new HttpClient();
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;

    var response = client
                     .PostAsync(uri, new StringContent(jsonData, Encoding.UTF8, "application/json")
                     .GetAwaiter().GetResult();
    return response;
}

但更好的方法当然是在调用堆栈中使用 async/await。

【讨论】: