C# httpclient with Task<string> that return content

C# httpclient with Task<string> that return content

我有以下功能,但无法调试它,因为没有响应。另一边的服务正在运行。任何帮助都会得到预估,我无法推断出必须如何使用 SO

中的其他答案
    public async Task<string> PostObjectToWebServiceAsJSON(object objectToPost, string validatorName, string method)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("myuri" + "/" + method);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            // HTTP POST
            var response = await client.PostAsJsonAsync("", objectToPost);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else
            {
                string errplugin = "Error";

                return null;
            }
        }
    }

我是这样称呼它的:

    public PaymentResponseInternal Post(some stuff here)
    {
        Task<string> retornoPluginAsync = PostObjectToWebServiceAsJSON(some stuff here);

        retornoPluginAsync.Wait();
        string result = retornoPluginAsync.Result;

        return JsonConvert.DeserializeObject<PaymentResponseInternal>(result);
    }

随着您对问题的更新,当您同步调用 PostObjectToWebServiceAsJSON 时,您 运行 陷入了死锁状态。您应该在 Wait() 之前添加对 retornoPluginAsync.ConfigureAwait(false); 的调用。 ConfigureAwait(false)Task 配置为不需要原始调用上下文,并且在您的情况下应该解决死锁。

    public PaymentResponseInternal Post(some stuff here)
    {
        Task<string> retornoPluginAsync = PostObjectToWebServiceAsJSON(some stuff here);
        retornoPluginAsync.ConfigureAwait(false); // Add this
        retornoPluginAsync.Wait();
        string result = retornoPluginAsync.Result;

        return JsonConvert.DeserializeObject<PaymentResponseInternal>(result);
    }

如评论中所述,您应该使 PaymentResponseInternal 成为 async 方法,returns 成为 Task<PaymentResponseInternal> 并等待它。

你不应该混合使用同步和异步代码。原因之一是您可能会像您在此处发现的那样陷入僵局。有关更多信息,请参阅@Stephen Cleary 关于该主题的文章:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

如果您由于某种原因无法使 Post 方法 async,您可以尝试不通过调用 ConfigureAwait(false) 来捕获 PostObjectToWebServiceAsJSON 方法中的上下文在每个 await:

之后
public async Task<string> PostObjectToWebServiceAsJSON(object objectToPost, string validatorName, string method)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("myuri" + "/" + method);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var response = await client.PostAsJsonAsync("", objectToPost).ConfigureAwait(false);
        if (response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
        else
        {
            return null;
        }
    }
}

有关此信息,请参阅@Stephen Cleary 的博客post:https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html