RunningProcess Type
A live handle to a started process: stream its output, feed its stdin, wait for it, or collect it to completion. Disposing it reaps the whole process tree (kill-on-drop).
Instance members
| Instance member |
Description
|
|
Cumulative CPU time (user + kernel) of the child right now, if the platform reports it and the process is still alive.
|
Full Usage:
this.DroppedStreamLineCount
Returns: int
|
Lines dropped so far by a bounded streaming policy's `StreamFullMode.DropOldest`/`DropNewest` (always `0` unless `Command.StreamBuffer` is configured with one of those modes) — the streaming analogue of a buffered verb's `ProcessResult.Truncated`.
|
|
Wall-clock time since the process started.
|
|
After streaming stdout, wait for exit and return the captured stderr. Reaps the tree.
|
Full Usage:
this.Kill
|
Signal the process tree to die without waiting (fire-and-forget, like `Process.Kill()`); the tree is fully reaped when the handle is disposed. For a blocking kill, dispose the handle. |
|
Run to completion, capturing stdout as raw bytes (no line splitting) and stderr as text. The configured `OutputBuffer` policy's **byte** controls apply to this raw stdout capture: `MaxBytes = Some cap` enforces the cap per `Overflow` — `Error` returns `ProcessError.OutputTooLarge` once the cumulative stdout exceeds the cap (the pipe is still drained), `DropOldest` keeps the last `cap` bytes, `DropNewest` keeps the first `cap` bytes, both setting `ProcessResult.Truncated` when anything was dropped. `MaxBytes = None` (the default) keeps the raw capture **unbounded** — there is no byte ceiling to enforce. `MaxLines` never applies to a raw byte stream (it has no line structure) and is ignored on stdout here; it still governs the line-pumped **stderr** capture. `Truncated` reflects truncation of stdout OR stderr, and `OutputTooLarge` fires if either stream trips its fail-loud ceiling. This is a deliberate, documented divergence from the Rust `ProcessKit-rs` reference, whose `output_bytes` bounds raw bytes only by `Timeout`, not by the buffer policy: a caller who set `MaxBytes`/`FailLoud` to bound memory would still get an unbounded stdout buffer otherwise.
|
|
Stream merged stdout+stderr line events as they arrive, each tagged with its origin (`OutputEvent.Stdout`/`OutputEvent.Stderr`). Under `Command.MergeStderr` the child has no separate stderr stream (it is folded into stdout at the OS level), so every event is an `OutputEvent.Stdout` — the stderr lines are already interleaved, in order, within the stdout byte stream.
|
|
Run to completion, capturing stdout as decoded text. A non-zero exit is data; the tree is reaped when the call returns.
|
Full Usage:
this.PeakMemoryBytes
Returns: int64 option
|
Peak resident memory of the child in bytes, if reported (some platforms, e.g. macOS, may not) and the process is still alive.
|
Full Usage:
this.Pid
Returns: int option
|
The pid, when known.
|
|
`ProfileAsync` sampling every 100 ms.
|
|
Run to completion while periodically sampling the child's CPU/memory every `interval`, and return a `RunProfile`. Drains and discards output (like `WaitAsync`) and reaps the tree.
|
|
When the process was started.
|
Full Usage:
this.StderrLineCount
Returns: int
|
Total stderr lines pumped so far.
|
Full Usage:
this.StdoutLineCount
Returns: int
|
Total stdout lines pumped so far (counts dropped lines too).
|
|
Stream stdout line by line as it arrives. Call `FinishAsync` afterwards for stderr + outcome.
|
|
|
|
Gracefully stop the process tree, then reap it: send the child a soft signal (SIGTERM), wait up to `gracePeriod` for it to exit on its own, then hard-kill whatever is still alive — the same graceful-kill machinery `Command.TimeoutGrace` and `ProcessGroup.ShutdownAsync` drive. Returns the honest `Outcome` of how the child *actually* concluded (a clean `Exited` if it obeyed the signal, otherwise a `Signalled`/`Exited` from the escalated kill); a non-zero or killed exit is data, never a raised error. Unlike the fire-and-forget `Kill()`, this awaits the stop and tears the tree down before returning, so it is a terminal verb like `WaitAsync`. This drains the child's stdout/stderr while it shuts down (a child blocked writing to a full pipe would otherwise ignore the soft signal until it could flush). If a streaming or capturing verb already owns the pipes, `StopAsync` reuses that session's wait rather than starting a second reader on them, so it is safe to call after `StdoutLinesAsync`/`OutputEventsAsync` or concurrently with an in-flight `FinishAsync`/`WaitAsync`. Idempotent and race-safe with `Kill`, `Dispose`, and a repeat `StopAsync`: the tree is reaped exactly once. **Platform / shared-group degradation (no new silent downgrade).** A soft signal needs a mechanism that has one. On **Windows** there is no per-tree graceful signal, so `gracePeriod` is skipped and this is the atomic Job kill — exactly as `Command.TimeoutGrace` and `ProcessGroup.ShutdownAsync` already degrade there (a console child can still get a best-effort CTRL+BREAK via `Command.WindowsCtrlSignals()` + `ProcessGroup.Signal`). On a **shared** group (a handle from `ProcessGroup.StartAsync`, where the group — not the handle — owns the tree) there is no per-child graceful signal either, so this immediately hard-kills just this child (like `Kill()`), matching the documented `TimeoutGrace` fallback for a shared group. A handle from the default runner (`Command.StartAsync()` / `IProcessRunner.SpawnAsync`) owns a private group and gets the full SIGTERM → grace → SIGKILL on Unix.
|
|
Take the interactive stdin handle — `Some` only when the command kept stdin open without a source attached, and only once.
|
|
|
Full Usage:
this.WaitForAsync
Parameters:
Func<Task<bool>>
timeout : TimeSpan
?cancellationToken : CancellationToken
Returns: Task<Result<unit, ProcessError>>
|
Poll `probe` until it returns true, or fail with `NotReady` once the shared `timeout` deadline elapses (or `Cancelled` if `cancellationToken` fires first). The deadline is honored even if `probe` never completes — or blocks synchronously without ever returning a task: the invocation is isolated on the thread pool and raced against the shared deadline, and the caller's token takes priority over a concurrent success. The API cannot force a caller-owned `probe` to stop, so an abandoned invocation keeps running in the background, but its late outcome is safely observed (a late fault never becomes an unobserved task exception). See `ReadinessProbe.waitForCore` for the full contract, including the ratified scheduler-bounded window at the deadline. Background-drains (and discards) the child's piped stdout/stderr for the duration of the poll, exactly like `WaitForPortAsync` — see its doc for what that does and doesn't compose with afterward.
|
Full Usage:
this.WaitForLineAsync
Parameters:
Func<string, bool>
timeout : TimeSpan
?cancellationToken : CancellationToken
Returns: Task<Result<string, ProcessError>>
|
Wait until a stdout line satisfies `predicate`, or fail with `NotReady` after `timeout` (or `Cancelled` if `cancellationToken` fires first). Consumed lines are not re-delivered; a later `StdoutLinesAsync`/`FinishAsync` sees the rest.
|
Full Usage:
this.WaitForPortAsync
Parameters:
IPEndPoint
timeout : TimeSpan
?cancellationToken : CancellationToken
Returns: Task<Result<unit, ProcessError>>
|
Wait until a TCP connection to `endpoint` succeeds, or fail with `NotReady` once the shared `timeout` deadline elapses (or `Cancelled` if `cancellationToken` fires first). Every connect attempt and polling backoff shares that one deadline, so a slow or non-cooperative connect can never overrun a short `timeout` — see `ReadinessProbe.waitForPortUsing` for the full contract, including the ratified scheduler-bounded window at the deadline. Background-drains (and discards) the child's piped stdout/stderr for the duration of the poll — like `WaitForLineAsync`, so a child that writes more than one OS pipe buffer of startup output (~64 KiB on Linux) before becoming ready can't block in `write()` and spuriously time out this probe — but unlike `WaitForLineAsync`, the drained bytes are discarded rather than handed back, and draining stops once the probe concludes rather than continuing as an established streaming session. A capture verb (`OutputStringAsync`/`OutputBytesAsync`/`StdoutLinesAsync`/`OutputEventsAsync`) called AFTER this probe therefore only sees what the child wrote after the probe concluded, not the full run — the same "doesn't compose with a subsequent fresh capture" limitation `WaitForLineAsync` already documents, now uniform across all three readiness probes. If a buffered/streaming verb already claimed the pipes before this call, that verb's own pump is already draining them and this probe leaves them alone (no second reader).
|
Static members
| Static member |
Description
|
Full Usage:
RunningProcess.WaitAllAsync(processes)
Parameters:
RunningProcess[]
Returns: Task<Outcome[]>
|
Wait for all of `processes` to exit; returns their outcomes in order. Does not reap them. `processes` must be non-null, non-empty, and free of null elements — each is a programmer error, not a process outcome, so it throws (`ArgumentNullException` for a null array, `ArgumentException` for an empty array or a null element) rather than reporting through a `Result`. Symmetric with `WaitAnyAsync` on all three axes: error channel, empty input, and null handling. If a pump backing one of the `ExitTask`s faults, that exception propagates unchanged from `Task.WhenAll` — also not wrapped in a `Result`.
|
Full Usage:
RunningProcess.WaitAnyAsync(processes)
Parameters:
RunningProcess[]
Returns: Task<WaitAnyResult>
|
Wait for the first of `processes` to exit; returns its index and outcome. Does not reap any of them — dispose them yourself. Safe to call on a handle a buffered verb (`OutputStringAsync`/ `OutputBytesAsync`/`WaitAsync`/`ProfileAsync`) already started: it reuses that verb's own wait (see `ExitTask`) rather than racing a second reader on the same pipes. `processes` must be non-null, non-empty, and free of null elements — each is a programmer error, not a process outcome, so it throws (`ArgumentNullException` for a null array, `ArgumentException` for an empty array or a null element) rather than reporting through a `Result`. Symmetric with `WaitAllAsync` on all three axes: error channel, empty input, and null handling. If a pump backing one of the raced `ExitTask`s faults, that exception propagates unchanged from the awaited task — also not wrapped in a `Result`.
|
ProcessKit API Reference