4

I'm creating an Instagram API client on ASP MVC using HttpClient, I'm trying to make a get request but it fails without throwing exception or responding and doesn't respond to my timeout. Here is my code:

 public class InstagramService
 {
    private HttpClient Client = new HttpClient {
       BaseAddress = new Uri("https://api.instagram.com/v1/"),
       Timeout = TimeSpan.FromMilliseconds(500)
    };
    public async Task<InstagramUser> GetInstagramUser(long? userId = null)
    {
       InstagramUser User = null;
       string Parameter = (userId == null) ? "self" : userId.ToString();
       try {
          var response = await Client.GetAsync("users/" + Parameter + "/" + GetAccessToken());
          if (response.IsSuccessStatusCode)
          {
              User = await response.Content.ReadAsAsync<InstagramUser>();
          }
      }catch(Exception e)
      {
          Console.WriteLine(e.Message);
          Console.WriteLine(e.InnerException.Message);
      }
      return User;
    }

    private string GetAccessToken()
    {
        return "?access_token=" + DB.config_det_sys.Single(i => i.codigo == "ACCESS_TOKEN_INSTAGRAM" && i.estado == true).Valor;
    }

 }

EDIT

Here I add how I call my service on the Home Controller, I will still test changing the controller to async Task

public class HomeController : Controller
{
    private InstagramService IGService = new InstagramService();
    public ActionResult About()
    {
       var apiCall = IGService.GetInstagramUser();
       var model = apiCall.Result;
       return View(model);
    }
}

I tested on Postman trying to make the API call and it indeed worked, so where I'm failing to catch errors?

3
  • 1
    How is the code being called? Make sure you are not making any blocking calls higher up the call stack Commented Dec 21, 2016 at 23:33
  • @Nkosi Here, I added a fragment of how I intend on callying the methods Commented Dec 22, 2016 at 2:13
  • check Stephen Cleary's answer. As I suspected you were making a blocking call on apiCall.Result which can result in a deadlock. Convert the action to use async/await Commented Dec 22, 2016 at 3:21

2 Answers 2

5

Your problem is here:

var model = apiCall.Result;

As I describe on my blog, you shouldn't block on asynchronous code. It can cause a deadlock.

Instead of Result, use await:

var model = await apiCall;
Sign up to request clarification or add additional context in comments.

2 Comments

I have a small doubt, If I create another private async method for the service that calls the GET Endpoints (because I need to add the access token on every call), calling three async awaitables could impact performance?
@Forcefield: Three async calls would not have a noticeable performance change at all.
2

Adding to Stephen's answer, update the controller's action to be async all the way.

public class HomeController : Controller {
    private InstagramService IGService = new InstagramService();
    public async Task<ActionResult> About() {
       var model = await IGService.GetInstagramUser();
       return View(model);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.