Reputation: 224
I am in a scenario wherein I need to call an exe process via an API endpoint (fire and forget). However, the exe that I will call is a long running one but I need to wait for it to finish to execute further codes. This will happen in the background and the client shouldn't really wait for it. When I'm trying the code below, the call is waiting for the exe process to finish. I've also tried making the method "async" but still same result.
[HttpPost]
public async Task<bool> ToggleCarWeaverService(string command)
{
try
{
var fileName = @"SomeExe.exe";
await _service.RunProcessAsync(command, fileName);
return true;
}
catch (Exception ex)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
public Task<int> RunProcessAsync(string command, string fileName)
{
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo
{
CreateNoWindow = false,
UseShellExecute = true,
FileName = fileName,
WindowStyle = ProcessWindowStyle.Normal,
Arguments = command
};
try
{
var tcs = new TaskCompletionSource<int>();
var process = new Process
{
StartInfo = startInfo,
EnableRaisingEvents = true
};
process.Exited += (sender, args) =>
{
tcs.SetResult(process.ExitCode);
//Do more code
process.Dispose();
};
process.Start();
return tcs.Task;
}
catch (Exception ex)
{
// Log error.
throw ex;
}
}
Upvotes: 1
Views: 1168
Reputation: 16705
The answers given here will, correctly, answer your question - that is, by not awaiting the result, your call will return immediately. However, there is no guarantee that the process will continue to run. Once you've left the function you, effectively, have a rouge process that may or may not complete.
Most Cloud providers have a solution to this (e.g. Azure WebJobs), or you could roll your own using something like HangFire.
Upvotes: 2
Reputation: 247571
Do not await the async task.
Use Task.Run
to wrap and continue
[HttpPost]
public IHttpActionResult ToggleCarWeaverService(string command) {
Task.Run(async () => {
var fileName = @"SomeExe.exe";
await _service.RunProcessAsync(command, fileName);
//...other code after process finish
});
return Ok();
}
Upvotes: 2
Reputation: 77926
Then you shouldn't await
the call further at all and thus change the line where you await the call RunProcessAsync
to
_service.RunProcessAsync(command, fileName);
Upvotes: 1