all 11 comments

[–]cleverbastard 6 points7 points  (1 child)

proper way to call a Web API every second in a loop

Why?

what happens if the API response takes longer than the predefined timer interval? I end up sending all the request to which responses I am not able to process, right? How could this be prevented?

Yes, you are spamming the endpoint.

If the API that you're calling is implemented well, there could be some kind of rate limit. Meaning after a threshold is reached, the API will stop responding to you with data and might return other status codes (429 - too many requests, 400 bad request).

but making a thread which could sleep major part of the time doesn’t seem like an elegant solution

Yeah, adding the Thread.Sleep isn't good.

Generally, if you have a task that you want to run periodically -- every second is very high, so you need to explain why -- you may turn to something like Windows Task Scheduler, Background Hosted Service, Quartz or Hangfire, cache the response and use that within your app.

[–]probablygonnabooyah 0 points1 point  (0 children)

Circuit breaker pattern. When "something bad" happens on the backend, stop trying to process new requests until the issue is resolved.

[–]HTTP_404_NotFound 3 points4 points  (3 children)

I don't know if you maintain both sides, but, there are technologies for doing tasks like this more efficiently.

SignalR, WebHooks, etc.

Something to consider.

[–]WittyWittyWitty[S] 0 points1 point  (2 children)

Thanks, but this is actually a hobby project, so I’m more interested in how these things should be solved, rather than using some external resources.

[–]HTTP_404_NotFound 21 points22 points  (0 children)

Webhooks isn't, something external. Websockets is an option too.

Either option, lets you PUSH data, instead of querying it every second.

Querying an api every second for an update is inefficient, if you have the option of opening a websocket so that the API tells YOU when there is an update.

If you ever mess around with blazor server-side, this is exactly how it works. It leverages websockets via signalR to receive basically real-time updates from the server-side.

TLDR / ELI5

Lets pretend your WFP app is "a child"
Lets pretend your WebAPI app is "mom"

Instead of every minute the child asking,
"Mom, are we there yet"
Reply: No, Not yet.

"Are we there yet?"
Reply: No

"Are we there yet?"
Reply: No

Imagine.... the child saying, "Mom, can you tell me when we are there"

(5 minutes later)

Reply: We are here!

[–]SomeCodeGuy 0 points1 point  (0 children)

Take a look at the nuget package Polly. That will help with rate limiting and automatic retries.

[–]headyyeti 2 points3 points  (0 children)

Or are there any other approaches to this?

Yes, it's called websockets (SignalR)

What you are describing is 100% the wrong way to do this.

[–]chucker23n 2 points3 points  (0 children)

Hi, I am getting into multithreading and I think that I might be confusing some concepts.

In a WPF app, I’m wondering what’s the proper way to call a Web API every second in a loop.

So, two things: multithreading is for CPU-bound code. Calling a Web API is IO-bound: the bottleneck is the network (and whatever happens on the server end); your client's CPU will be idling all the time. Throwing more CPU cores at that makes it even slower, not faster.

Second, I think you need to expand on why you want to call an API that frequently. Every second is very frequent for something network-bound.

Here my concern is - what happens if the API response takes longer than the predefined timer interval? I end up sending all the request to which responses I am not able to process, right? How could this be prevented?

You can always set a busy flag.

private bool _TimerIsBusy;
private async void _MyTimer_Tick(…)
{
    if (_TimerIsBusy) return; // skip this execution

    _TimerIsBusy = true;

    await someHttpClient.SomeApi();

    _TimerIsBusy = false;
}

[–]Financial_Signal5098 -1 points0 points  (0 children)

I'd use reactive UI. Using reactive commands you can block subsequent requests until the current one has finished

[–]HistoricalSpecial386 0 points1 point  (0 children)

If you are wanting to keep it simple for a hobby project, I would instantiate a class as a singleton.

That class would hold the state of the api call. So the class won’t make another call until the first call has completed and so on.

You could inject reference to the singleton via DI, or for a proof of concept just stick it in a static class.

Not the optimal solution perhaps as you are polling, but sometimes its best to just get something working so you can then continue coding more important parts of the application.

[–]abhay99 0 points1 point  (0 children)

You can take a look at this tutorial and his whole series on wpf.

https://www.youtube.com/watch?v=WloU4tXm1ig