I am implementing a REST API endpoint in ASP.NET, that should do the following:
- Asynchronously start a long-running algorithm
- Return 202 Accepted immediately after starting the algorithm (no await)
This is what the endpoint looks like:
app.MapPut(
"/api/instance/{id}",
(int id, InstanceDto instanceDto, IInstanceRunningService service) =>
{
// Start the execution asynchronously and return ASAP
service.RunInstance(instanceDto);
return TypedResults.Accepted($"/api/instance/{id}");
})
This is what the RunInstance
method in the service looks like:
public async Task RunInstance(InstanceDto instanceDto)
{
// Asynchronously call another API that we are starting the execution of the algorithm
// We do not need to wait for the response, we just want to start the algorithm ASAP (again no await)
_ = this.AnotherApiClient.PutAsync(instanceDto);
// Compute the algorithm and await the result
var result = await Algorithm.Run(instanceDto.Parameters);
// Finally call the other API again to notify that the computation finished
await this.AnotherApiClient.PutAsync(instanceDto);
}
The order of operations I want to achieve is:
- Return 202 Accepted
- Notify another API that computation is starting (we don't care how this API call ends, because we will be sending another one in step 4.)
- Compute the algorithm
- Notify another API that computation has finished
I can't figure out the best way to achieve this. There are so many options:
service.RunInstance(instanceDto);
service.RunInstance(instanceDto).Start();
Task.Run(() => service.RunInstance(instanceDto))
- Make RunInstance an asynchronous delegate and do
delegate.BeginInvoke()
- Create a
Thread
or useThreadPool
- Maybe implement the service differently with more async methods