我正在使用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);
}

10-08 05:37