I am using the solution provided in: https://stackoverflow.com/a/19104345/2713516 to run WaitForExit async, however, I want to use the Int32 parameter overload (https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx), as in process.WaitForExit(10000).
How do I alter this extension method so it works with the timeout parameter?
Side question: I also saw someone mentioned (https://stackoverflow.com/a/32994778/2713516) that I should dispose the cancellationToken at some point, shouldn't I use a dispose/using within the method then? and How?
/// <summary>
/// Waits asynchronously for the process to exit.
/// </summary>
/// <param name="process">The process to wait for cancellation.</param>
/// <param name="cancellationToken">A cancellation token. If invoked, the task will return
/// immediately as canceled.</param>
/// <returns>A Task representing waiting for the process to end.</returns>
public static Task WaitForExitAsync(this Process process,
CancellationToken cancellationToken = default(CancellationToken))
{
var tcs = new TaskCompletionSource<object>();
process.EnableRaisingEvents = true;
process.Exited += (sender, args) => tcs.TrySetResult(null);
if(cancellationToken != default(CancellationToken))
cancellationToken.Register(tcs.SetCanceled);
return tcs.Task;
}
You'll need to alter the method signature and the apply the result from the process itself. For example consider the following:
/// <summary>
/// Waits asynchronously for the process to exit.
/// </summary>
/// <param name="process">The process to wait for cancellation.</param>
/// <param name="cancellationToken">A cancellation token. If invoked, the task will return
/// immediately as canceled.</param>
/// <returns>A Task representing waiting for the process to end.</returns>
public static Task WaitForExitAsync(this Process process,
int milliseconds,
CancellationToken cancellationToken = default(CancellationToken))
{
if (process.HasExited)
{
return Task.CompletedTask;
}
var tcs = new TaskCompletionSource<object>();
process.EnableRaisingEvents = true;
process.Exited += (sender, args) => tcs.TrySetResult(null);
if (cancellationToken != default(CancellationToken))
{
cancellationToken.Register(tcs.SetCanceled);
}
return process.HasExited
? Task.CompletedTask
: Task.WhenAny(tcs.Task, Task.Delay(milliseconds));
}
Now, if the process has not ended the task will still be returned after the delay. An alternative would be to do a Task.Run with the invocation to the desired overload like this:
/// <summary>
/// Waits asynchronously for the process to exit.
/// </summary>
/// <param name="process">The process to wait for cancellation.</param>
/// <param name="cancellationToken">A cancellation token. If invoked, the task will return
/// immediately as canceled.</param>
/// <returns>A Task representing waiting for the process to end.</returns>
public static Task WaitForExitAsync(this Process process,
int milliseconds,
CancellationToken cancellationToken = default(CancellationToken)) =>
process.HasExited
? Task.CompletedTask
: Task.Run(() => process.WaitForExit(milliseconds), cancellationToken);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With