Here we have a requirement that in the ASP.NET Core Web API controller, a job should be created and executed in the background, and the controller should reply the response immediately once the job starts running. There will be another controller API which could query the execution status of the job but that is a different topic.
To be simpler, the code is similar to the following:
public class Job
{
public async Task RunAsync()
{
//...
}
}
// API Controller code
private Job _job;
[HttpPost]
public async Task<IActionResult> CreateJob()
{
_job.RunAsync(); // <-- No awaiting, making the job running in the background
await DoAnotherThingAsync();
return Ok();
}
I found that sometimes the running of this background job will be interrupted for some reasons - After this CreateJob API has returned, it looks like the _job.RunAsync() will not always completely finish its work - its execution thread could be killed at any time.
I know this is not a good implementation, but there are some questions:
- Why could this background job execution be interrupted?
- If I append
awaitbefore_job.RunAsync(), thisCreateJobAPI will eventually wait the background job to complete before it returns to the caller, which makes the job execution to be synchronous, right? - Except adopting third party frameworks like Quartz.NET and Hangfire, is there any simple solution to this issue?
Yup.
Any number of reasons! I explain several of them in my blog post (see the section "Shutdowns Are Normal"):
In-memory work cannot survive application shutdown (and shutdowns are normal), so the only proper (reliable) solution is to store them somewhere durable (i.e., not in memory).
Well, that depends on what you mean by "synchronous".
I would say that no, it's still asynchronous. With the
await, the request thread is not blocked, so it's asynchronous.But: ASP.NET will (asynchronously) wait until the job completes before returning the HTTP response.
Since ASP.NET doesn't return the HTTP response until the job is completed, then at a higher conceptual level you could say it was "synchronous".
No.
I have a blog series on this subject explaining why it's complex. Hangfire is about as simple of a solution as you're going to get.