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