Чтобы расширить ответы с упоминанием Task
и await
вещи
Если вы хотите превратить ожидание в асинхронный поток c, вы можете объединить событие Exited
с TaskCompletionSource
следующим образом:
public static class ProcessExtension
{
public static Task WaitForExitAsync(this Process proc, Action callback)
{
return new WaitForExitExt(proc, callback).WaitTask;
}
class WaitForExitExt
{
private TaskCompletionSource<int> _tcs;
private Action _callback;
public WaitForExitExt(Process proc, Action callback)
{
_callback = callback;
proc.EnableRaisingEvents = true;
_tcs = new TaskCompletionSource<int>();
if (proc.HasExited)
{
_tcs.TrySetResult(proc.ExitCode);
}
else
{
proc.Exited += OnProcessExited;
// Process already exited by the time the handler was attached.
if (proc.HasExited)
{
proc.Exited -= OnProcessExited;
_tcs.TrySetResult(proc.ExitCode);
}
}
}
public Task WaitTask => _tcs.Task;
private void OnProcessExited(object sender, EventArgs e)
{
var proc = (Process)sender;
proc.Exited -= OnProcessExited;
_callback();
_tcs.TrySetResult(proc.ExitCode);
}
}
}
Вышеприведенное расширение позволяет запускать callback
после завершения процесса, и гарантированно будет выполняться callback
до завершения задачи, так что вы можете использовать его в своем коде, например:
var process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.EnableRaisingEvents = true;
process.Start();
var task = process.WaitForExitAsync(() => Console.WriteLine("Exited"));
process.Kill();
await task;
Console.WriteLine("Task finished");
И вывод:
Exited
Task finished