Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call from Web API to another Web API without waiting for results

Is there a way to fire an Http call to an external web API within my own web API without having to wait for results?

The scenario I have is that I really don't care whether or not the call succeeds and I don't need the results of that query.

I'm currently doing something like this within one of my web API methods:

var client = new HttpClient() { BaseAddress = someOtherApiAddress };
client.PostAsync("DoSomething", null);

I cannot put this piece of code within a using statement because the call doesn't go through in that case. I also don't want to call .Result() on the task because I don't want to wait for the query to finish.

I'm trying to understand the implications of doing something like this. I read all over that this is really dangerous, but I'm not sure why. What happens for example when my initial query ends. Will IIS dispose the thread and the client object, and can this cause problems at the other end of the query?

like image 995
Gabriel G. Roy Avatar asked Oct 19 '22 10:10

Gabriel G. Roy


2 Answers

Is there a way to fire an Http call to an external web API within my own web API without having to wait for results?

Yes. It's called fire and forget. However, it seems like you already have discovered it.

I'm trying to understand the implications of doing something like this

In one of the links in the answers you linked above state the three risks:

  1. An unhandled exception in a thread not associated with a request will take down the process. This occurs even if you have a handler setup via the Application_Error method.

This means that any exception thrown in your application or in the receiving application won't be caught (There are methods to get past this)

  1. If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time. A little more challenging to deal with than the first item, but still not too hard. One typical approach is to use a resource common to all the servers, such as the database, as a synchronization mechanism to coordinate tasks.

You could have multiple fire-and forget calls when you mean to have just one.

  1. The AppDomain your site runs in can go down for a number of reasons and take down your background task with it. This could corrupt data if it happens in the middle of your code execution.

Here is the danger. Should your AppDomain go down, it may corrupt the data that is being sent to the other API causing strange behavior at the other end.

like image 188
Dudemanword Avatar answered Oct 22 '22 00:10

Dudemanword


I'm trying to understand the implications of doing something like this. I read all over that this is really dangerous

Dangerous is relative. If you execute something that you don't care at all if it completes or not, then you shouldn't care at all if IIS decides to recycle your app while it's executing either, should you? The thing you'll need to keep in mind is that offloading work without registration might also cause the entire process to terminate.

Will IIS dispose the thread and the client object?

IIS can recycle the AppDomain, causing your thread to abnormally abort. Will it do so depends on many factors, such as how recycling is defined in your IIS, and if you're doing any other operations which may cause a recycle.

In many off his posts, Stephan Cleary tries to convey the point that offloading work without registering it with ASP.NET is dangerous and may cause undesirable side effects, for all the reason you've read. That's also why there are libraries such as AspNetBackgroundTasks or using Hangfire for that matter.

The thing you should most worry about is a thread which isn't associated with a request can cause your entire process to terminate:

An unhandled exception in a thread not associated with a request will take down the process. This occurs even if you have a handler setup via the Application_Error method.

like image 23
Yuval Itzchakov Avatar answered Oct 22 '22 01:10

Yuval Itzchakov