HttpClient does not return anything
I am currently writing a method that makes a GET request to a server. The code I'm using for that is
For the endpoint, I'm currently using Mockoon until the actual server is ready. Now my call does not return. It neither comes back with an actual response nor does it throw the TaskCanceledException which it should after timing out. I've let it run for over 2 minutes now and it never reaches the exception nor the if statement right below the call. How can that happen?
Mockoon logs the call and also seems to send something back, but this never arrives apparently.
I can use call the endpoint successfully using postman, so that can't be it...
13 Replies
As additional information:
I'm calling all this from the UI thread using
.GetAwaiter().GetResult()
. I know this is bad practice because it blocks the UI thread for the calls duration, but in this case this does not matter since the user isn't supposed to do anything anyways until the call returns something.Try with the same code in a console app, using a real async main
Narrow down the issue
Also, there is an extensionmethod to make a get request and deserialize the response as a given JSON model, iirc it's called
GetAsJson
Wait I think I solved it.... I took the
.GetAwaiter().GetResult()
away from the call and put it into a
Task.Run(() => Call())
It now runs on a different thread and seems to work...
Maybe I don't understand async programming enough to understand why this solved it... It doesn't make sense to my why the actual call itself would not return in the previous solution
The problem is I NEED the UI thread to be blocked. The UI waits for the response and than closes when it was successful or shows a warning when it was not.you never want the UI thread to be blocked, that will prevent normal things like dragging/resizing the window
if that remote server goes down or gets slow do you want your interface to appear like it's not responding?
Yes. The application itself is not a UI based application, it runs only in the background. Also, the actual GUI is only used once, when the user starts the application for the first time, they need to enter a product key which is then checked using the api call. And I want this window to be blocked during the call so that it is visible that you should not do anything with it while it is checking.
But I have solved it. I now have the
Task.Run
but with the .Wait()
method attached. This blocks the UI, waits for the response AND the call does not get swallowed anymore. It works fine now
But I am absolutely with you that in most cases, the UI thread should not be blockedit's really not most, it's all
if the window message pump stalls windows will show it as "not responding"
Just disable the controls or show a progress bar
If your UI thread is blocked it can't pump messages, which means Windows will show the app as not responding
The user will then likely assume your app has crashed, and force quit it
There is never ever a reason to block the UI thread
It's always the result of a programming error
Also, in Forms or WPF, blocking on a Task can $deadlock @Turwaith
Don't Block on Async Code
This is a problem that is brought up repeatedly on the forums and Stack Overflow. I think it’s the most-asked question by async newcomers once they’ve learned the basics.
How would I then solve this better so that I don't block the UI thread. I will give you the code that is needed.
And this is where this is called from my viewmodel:
I need the window to stay open until the call comes back or cancels and then react accordingly
If what you're trying to accomplish is informing the user they're not supposed to do anything, then just do that
Show a status message, show a progress bar, disable the controls, something like that
Yeah but how do I do that in the context of async programming? Task.Run will put the actual call into another thread, that's fine. And without the .Wait() the code will continue running immediately.
So I need the window to react somehow to the request-thread returning its task. Do I fire an event from there? Or how do I make that the UI threads knows when the call is finished and has returned?
Task.Run vs BackgroundWorker: Intro
This is an introductory post for a new series that I’ll be doing comparing BackgroundWorker to Task.Run (in an async style). I always recommend Task.Run, and I have already written a long post describing why, but I still see some developers resisting the New Way of Doing Things (TM). So this will be a short series where I’ll compare the code sid...
This is about comparing to background worker, but it shows the general pattern of using a task to do background work in a GUI app
just ignore the BackgroundWorker bits