7

I'm using RestSharp to do a GET request Asynchronously but it never ends. If I do the same request Synchronously it ends successfully. I have used RestSharp just like this before and it always worked.

What am I doing wrong?

Here's the async method: (this.Client is just localhost)

public async Task<ServiceResponse> UpvoteArticleAsync(string source, string url)
{
    var client = this.Client;
    var request = new RestRequest("service/upvote/"+source+"/"+url, Method.GET) { RequestFormat = DataFormat.Json };
    var cancellationTokenSource = new CancellationTokenSource();
    var deserial = new JsonDeserializer();

    var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);

    return deserial.Deserialize<ServiceResponse>(response);
}

and this is how I call it:

ServiceResponse result = await rest.UpvoteArticleAsync (this.article.Source, this.article.Url);

As I said if I change the async method to a sync one, it works:

public async Task<ServiceResponse> UpvoteArticleAsync(string source, string url)
{
    var client = this.Client;
    var request = new RestRequest("service/upvote/"+source+"/"+url, Method.GET) { RequestFormat = DataFormat.Json };
    var cancellationTokenSource = new CancellationTokenSource();
    var deserial = new JsonDeserializer();

    var response = client.ExecuteTaskAsync(request, cancellationTokenSource.Token);

    return deserial.Deserialize<ServiceResponse>(response.Result);
}

EDIT:

I used try and catch to see if there's any exceptions but it didn't throw any.

EDIT 2:

Even if I do the same request with HttpWebRequest from System.Net it still gets stuck when using the async version of GetResponse:

public async Task<bool> UpvoteArticleAsync(string source, string url)
{
    var request = HttpWebRequest.Create(string.Format(@"http://192.168.43.199:8080/service/upvote/{0}/{1}", source, url));
    request.ContentType = "application/json";
    request.Method = "GET";

    using (HttpWebResponse response = await request.GetResponseAsync () as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
            Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            var content = reader.ReadToEnd();
            if(string.IsNullOrWhiteSpace(content)) {
                Console.Out.WriteLine("Response contained empty body...");
            }
            else {
                Console.Out.WriteLine("Response Body: \r\n {0}", content);
            }
        }
    }
    return true;
}
Vahid Amiri
  • 10,769
  • 13
  • 68
  • 113
  • Add a `try catch` and check is there any error occurs. Your sync version should `client.ExecuteTask(request,cancellation.Token)` mixing of async and await is not a good practice. – Eldho Jan 27 '16 at 12:24
  • Did you read [this question](http://stackoverflow.com/questions/34995195/asyc-method-using-await-task-run-never-completes#comment57718763_34995195)? – René Vogt Jan 27 '16 at 12:25
  • @StephenBrickner That's not needed because I'm awaiting it. – Vahid Amiri Jan 27 '16 at 12:26
  • In your first version put a breakpoint on your return statement and see what type the response is. It's not that it's not ending it's just not able to serialize what is being returned. Awaiting it will unwrap the response but that may still be an object of which you need to take the result out of a property. – Stephen Brickner Jan 27 '16 at 12:35
  • @StephenBrickner It never reaches the return. – Vahid Amiri Jan 27 '16 at 12:37
  • Is this a long running process? Add .ConfigureAwait(false); to the end of your line: ExecuteTaskAsync().ConfigureAwait(false);. It may be that it's just taking a long time and you've locked your UI thread. – Stephen Brickner Jan 27 '16 at 12:45
  • @StephenBrickner No. It's not. In fact it's done almost instantly with the sync version. – Vahid Amiri Jan 27 '16 at 12:47
  • Have you looked at this similar question/answer? I would look further up the call stack to ensure that you are not blocking somewhere and causing a deadlock. http://stackoverflow.com/a/12701927/1260204 – Igor Jan 27 '16 at 14:03
  • In your second example, where you say you're calling a synchronous method, you're still calling `ExecuteTaskAsync` -- typo? – Petter Hesselberg Jan 27 '16 at 14:16
  • @PetterHesselberg, Second method works fine and it's not a typo, it's an Async method but without `await` it's essentially a Sync method. – Vahid Amiri Jan 27 '16 at 14:59
  • Really? I would expect it to return a `Task` rather than a `WebResponse` or whatever the class name is. If you replace all your `var`s with the actual types, what do they show? – Petter Hesselberg Jan 27 '16 at 15:07
  • @PetterHesselberg It returns a `Task` and that's why I'm doing `response.Result` in the return statement. I could call the property `Result` on the async call instead but that makes no difference. – Vahid Amiri Jan 27 '16 at 15:25
  • We're having an identical problem, also with RestSharp. Our salient line of code looks like: var response = await client.ExecuteTaskAsync(request).ConfigureAwait(false);. About one in 100,000 calls deadlocks. We're running in a service, not MVC or UI and the stack is fully async complaint (nobody up the chain is calling wait or result). Additionally none of our other async calls sych as to entity framework manifest this behavior. Until we can figure this out we were forced to use the synchronous variant. – 42vogons Mar 24 '16 at 20:26
  • @42vogons, I ended up removing the request completely and changed the functionality of that part of the app, Because we couldn't afford to use the synchronous solution (Being a mobile app, we can't freeze the app otherwise OS would kill it) – Vahid Amiri Mar 25 '16 at 08:22

0 Answers0