我正在使用https://stackoverflow.com/a/19104345/2713516中提供的解决方案来运行WaitForExit异步,但是,我想像在process.WaitForExit(10000)中一样使用Int32参数重载(https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx)。
如何更改此扩展方法,使其与timeout参数一起使用?
附带问题:我还看到有人提到(https://stackoverflow.com/a/32994778/2713516),我应该在某个时候处理cancelToken,那我不应该在方法内使用dispose / using吗?如何?
/// <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;
}
最佳答案
您将需要更改方法签名,并应用流程本身的结果。例如,考虑以下内容:
/// <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))
{
var tcs = new TaskCompletionSource<object>();
process.EnableRaisingEvents = true;
process.Exited += (sender, args) => tcs.TrySetResult(null);
if (cancellationToken != default(CancellationToken))
{
cancellationToken.Register(tcs.SetCanceled);
}
return Task.WhenAny(tcs.Task, Task.Delay(milliseconds));
}
现在,如果进程尚未结束,则延迟后仍将返回任务。一种替代方法是对所需的重载进行
Task.Run
调用,如下所示:/// <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))
{
return Task.Run(() => process.WaitForExit(milliseconds), cancellationToken);
}