/// <summary> /// Waits until the process either finishes on its own or when user cancels the action. /// </summary> /// <param name="cancel">Cancellation token.</param> /// <param name="killOnCancel">If <c>true</c> the process will be killed (with entire process tree) when this asynchronous action is canceled via <paramref name="cancel"/> token.</param> /// <returns><see cref="Task"/>.</returns> public async Task WaitForExitAsync(CancellationToken cancel, bool killOnCancel = false) { if (Process.HasExited) { return; } try { // If this token is already in the canceled state, the delegate will be run immediately and synchronously. using (cancel.Register(() => ProcessExecutionTcs.TrySetCanceled())) { await ProcessExecutionTcs.Task; } } catch (OperationCanceledException ex) { if (killOnCancel) { if (!Process.HasExited) { try { Process.Kill(entireProcessTree: true); } catch (Exception e) { Logger.LogError($"Could not kill process: {e}."); } } } throw new TaskCanceledException("Waiting for process exiting was canceled.", ex, cancel); } }
private void OnExited(object?sender, EventArgs?e) { ProcessExecutionTcs.TrySetResult(true); }