process.WaitForExit(int32) 异步
process.WaitForExit(int32) asynchronously
我正在使用 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) 中提供的解决方案,如 process.WaitForExit(10000).
如何更改此扩展方法以使其与超时参数一起使用?
附带问题:我还看到有人提到 () 我应该在某个时候处理 cancellationToken,我不应该使用 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))
{
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));
}
现在,如果进程没有结束,任务仍然会在延迟后返回。另一种方法是通过调用所需的重载来执行 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)) =>
process.HasExited
? Task.CompletedTask
: Task.Run(() => process.WaitForExit(milliseconds), cancellationToken);
}
我正在使用 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) 中提供的解决方案,如 process.WaitForExit(10000).
如何更改此扩展方法以使其与超时参数一起使用?
附带问题:我还看到有人提到 () 我应该在某个时候处理 cancellationToken,我不应该使用 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))
{
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));
}
现在,如果进程没有结束,任务仍然会在延迟后返回。另一种方法是通过调用所需的重载来执行 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)) =>
process.HasExited
? Task.CompletedTask
: Task.Run(() => process.WaitForExit(milliseconds), cancellationToken);
}