4

So apparently HttpClient only allows for Asnyc calls?

Of course you can call ".Result" like so:

public ActionResult Index()
{


            var someImportantData = httpClient.ReadAsStringAsync().Result;  // Aparently I shouldn't do this according to the article.
            // or    
            var someImportantData = Task.Run(() => Client.PostAsync()).Result;

            Return View( new MyViewModel(someImportantData));
}

to make it synchronous but this is apparently very dangerous and should be avoided because it causes deadlocking as described here.

So what are my options for Synchronous requests? I'm I going to be force to use the older HttpWebRequest? In my specific MVC action I want the call to be synchronous as I don't want to return the page until I collect data from a restful api call.

9
  • 3
    I don't want to return the page until I collect data from a restful api. How do async calls prevent you to do it? Commented Aug 16, 2017 at 22:23
  • @L.B I want my current thread to not proceed ( i.e: be synchronous ) and wait for the api call to return, then I can re-direct to the new page. Commented Aug 16, 2017 at 22:32
  • 2
    There is no problem in using async/await in MVC. Can you show your case which doesn't work? Commented Aug 16, 2017 at 22:46
  • 3
    "...I don't want to return the page until" you will not return back to the page even with aysnc/await can you post your sample code? Commented Aug 16, 2017 at 22:54
  • 2
    Task.Run() should also be avoided in ASP.Net. Commented Aug 16, 2017 at 23:06

2 Answers 2

3

If using async APIs then you should make your code async all the way. You can just as easily await the async members.

public async Task<ActionResult> Index() {
    var someImportantData = await httpClient.ReadAsStringAsync(...);
    return View(new MyViewModel(someImportantData));
}

I want my current thread to not proceed ( i.e: be synchronous ) and wait for the API call to return, then I can redirect to the new page.

The above call won't return the page until you collect data from the restful API call. Everything after the await will be back on the original thread.

.Result causes deadlocks as described in the article.

Yes. You sould avoid mixing async and blocking calls.

Sign up to request clarification or add additional context in comments.

3 Comments

RayLoveless, After reading the answer read my first comment again. @Nkosi +1
@L.B. Yeah, my original code example wasn't very helpful. Thanks. This helps a bunch. Under the covers, i imagine the first thread must be listening for an interrupt so it can continue after the call returns( and not block)
What if I have an interface where I get my data from and I want to change the implementation of that interface to get the data from a rest end point(the whole reason why to use an interface!!) ...without the support of a synchronous http calls I would have to change my interface signatures as well.. and all the signatures that depend on that interface.
0

You do not really need to use .Result here. You can simply await for the result:

For example:

public async Task<ActionResult> Index()
{
      var someImportantData = await httpClient.ReadAsStringAsync().ConfigureAwait(false); 
      return View( new MyViewModel(someImportantData)); // This line will not be called until previous line is completed.
}

Use of ConfigureAwait(false) optional. If you are not using ASP.NET Core, then it can help a bit since you do not need to capture the context for server side code. Refer this link.

3 Comments

Since OP wants to continue in a thread/context he lelt, .ConfigureAwait(false); is not an option. If we remove that code, what is different than other answer?
Do not see anything specific on that in the question now. May be the question edited. I have also mentioned it optional. But, do you think it could be an issue if context is changed for any scenario?
Do not see anything specific on that in the question now Comments are also part of this question.

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.