Reputation: 451
I'm pulling data from Amazon via HTTP. The code works just fine in a small demo project, but in my main app it doesn't. When I call FetchItem()
I receive this output:
'System.Net.Http.Formatting.dll'. Cannot find or open the PDB file.
After await client.GetAsync()
the function returns and url.Wait()
waits forever.
Usage
Task<string> url = FetchItem("ItemName", requestUrl);
url.Wait();
return url.Result;
Source of FetchItem
private static async Task<string> FetchItem(string sItemName, string url)
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
XElement content = await response.Content.ReadAsAsync<XElement>();
XNamespace ns = NAMESPACE;
var isValidResults = content.Descendants(ns + "IsValid").AsParallel();
foreach (var item in isValidResults)
{
if (item.Value != "True")
return "Invalid Request";
}
var titleResults = content.Descendants(ns + sItemName).AsParallel();
foreach (var item in titleResults)
{
if (item.Name == ns + sItemName)
return item.Value;
// depending on the keyword, results can be quite fun.... :-)
}
}
catch (Exception e)
{
System.Console.WriteLine("Caught Exception: " + e.Message);
System.Console.WriteLine("Stack Trace: " + e.StackTrace);
}
return "Error";
}
Upvotes: 1
Views: 5889
Reputation: 451
I changed FetchItem()
to run sync. That did it for me:
private static string GetItem(string sItemName, string url)
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
XElement content = response.Content.ReadAsAsync<XElement>().Result;
...
It doesn't make sense to me to rewrite half my app to go async.
Upvotes: 0
Reputation: 292415
I assume you're calling this code on the UI thread. What's happening is that Wait
ing for the task to complete causes a deadlock. Your FetchItem
method is asynchronous, and when you use await
in it, the code that follows is transformed to a callback (called the continuation) that will be executed on the UI thread. But since the UI thread is busy waiting for the task to complete, it can't process the callback, so the task never completes. Hence the deadlock.
You should never Wait
on the result of an async method. If you call an async method, use await
to get its result. It means that the calling method also has to be async. Basically, when you start to use async in some part of the code, all the code that uses it needs to become async as well... (*)
(*) well, that's not exactly true. You can prevent the async method from resuming on the UI thread, by calling ConfigureAwait(false)
on the method you await
. If you do that, the continuation will run on a thread pool thread, instead of the UI thread. This will also avoid the deadlock.
Upvotes: 3