Reputation: 11588
I've the following function but can't debug it because response never come. Service on the other side is working. Any help will be preciated, I can't deduce how must be do it with other answers in 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;
}
}
}
This is how I call it:
public PaymentResponseInternal Post(some stuff here)
{
Task<string> retornoPluginAsync = PostObjectToWebServiceAsJSON(some stuff here);
retornoPluginAsync.Wait();
string result = retornoPluginAsync.Result;
return JsonConvert.DeserializeObject<PaymentResponseInternal>(result);
}
Upvotes: 0
Views: 2970
Reputation: 169330
As mentioned in the comments, you should make PaymentResponseInternal
an async
method that returns a Task<PaymentResponseInternal>
and await it.
You shouldn’t mix synchronous and asynchronous code. One of the reasons for this is that you might deadlock as you have discovered here. Please refer to @Stephen Cleary's article on the subject for more information: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
If you can't make your Post
method async
for some reason, you could try not to capture the context in the PostObjectToWebServiceAsJSON
method by calling ConfigureAwait(false)
after each 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;
}
}
}
Please refer to @Stephen Cleary's blog post for information about this: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Upvotes: 3
Reputation: 2192
With your update to the question, you're running into a deadlock situation when you call PostObjectToWebServiceAsJSON
synchronously. You should add a call to retornoPluginAsync.ConfigureAwait(false);
before you Wait()
for it. ConfigureAwait(false)
configures the Task
to not require the original call context and should, in your case, solve the deadlock.
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);
}
Upvotes: 1