Skip to content

[API Proposal]: Add Signal and ProcessExitStatus members to Process #128322

Description

@tmds

Background and motivation

In .NET 11, several new APIs are added to SafeProcessHandle including sending signals, and retrieving exit status.

This proposal is for making these available on Process too.

API Proposal

namespace System.Diagnostics
{
    public partial class Process
    {
        /// <summary>
        /// Sends the specified signal to the process.
        /// </summary>
        /// <returns>true if the signal was sent successfully; false if the process has already exited.</returns>
        public bool Signal(PosixSignal signal);
            // => SafeHandle.Signal(signal);

        /// <summary>
        /// Waits for the process to exit and returns the exit status.
        /// </summary>
        public ProcessExitStatus WaitForExitStatus();
            // => SafeHandle.WaitForExit();

        /// <summary>
        /// Waits for the process to exit within the specified timeout and returns the exit status.
        /// </summary>
        /// <returns>true if the process exited within the timeout; otherwise, false.</returns>
        public bool TryWaitForExitStatus(TimeSpan timeout, [NotNullWhen(true)] out ProcessExitStatus? exitStatus);
            // => SafeHandle.TryWaitForExit(timeout, out exitStatus);

        /// <summary>
        /// Asynchronously waits for the process to exit and returns the exit status.
        /// </summary>
        public Task<ProcessExitStatus> WaitForExitStatusAsync(CancellationToken cancellationToken = default);
            // => SafeHandle.WaitForExitAsync(cancellationToken);

/* Existing methods:
        public void WaitForExit();
        public bool WaitForExit(int milliseconds);
        public bool WaitForExit(System.TimeSpan timeout);
        public Task WaitForExitAsync(CancellationToken cancellationToken = default);
*/
    }
}

Optionally, rename the (new .NET 11) methods on SafeProcessHandle that deal with ProcessExitStatus to also include ExitStatus in their name.

class SafeProcessHandle
{
...
-        public bool TryWaitForExit(TimeSpan timeout, out ProcessExitStatus? exitStatus);
-        public ProcessExitStatus WaitForExit();
-        public Task<ProcessExitStatus> WaitForExitAsync(CancellationToken cancellationToken = default(CancellationToken));
+        public bool TryWaitForExitStatus(TimeSpan timeout, out ProcessExitStatus? exitStatus);
+        public ProcessExitStatus WaitForExitStatus();
+        public Task<ProcessExitStatus> WaitForExitStatusAsync(CancellationToken cancellationToken = default(CancellationToken));
-        public Task<ProcessExitStatus> WaitForExitOrKillOnCancellationAsync(CancellationToken cancellationToken);
+        public Task<ProcessExitStatus> WaitForExitStatusOrKillOnCancellationAsync(CancellationToken cancellationToken);
-        public ProcessExitStatus WaitForExitOrKillOnTimeout(TimeSpan timeout);
+        public ProcessExitStatus WaitForExitStatusOrKillOnTimeout(TimeSpan timeout);

API Usage

Sending a signal to a process

using var process = Process.Start("myapp");

// Gracefully request termination.
process.Signal(PosixSignal.SIGTERM);

Waiting for exit status

using var process = Process.Start("myapp");

ProcessExitStatus status = process.WaitForExitStatus();
Console.WriteLine($"Exited with status: {status}");

Waiting with a timeout

using var process = Process.Start("myapp");

if (process.TryWaitForExitStatus(TimeSpan.FromSeconds(30), out ProcessExitStatus? status))
{
    Console.WriteLine($"Process exited: {status}");
}
else
{
    Console.WriteLine("Timed out, killing process.");
    process.Kill();
}

Async wait

using var process = Process.Start("myapp");

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
ProcessExitStatus status = await process.WaitForExitStatusAsync(cts.Token);
Console.WriteLine($"Process exited: {status}");

Notes

  • The names include ExitStatus to avoid conflicts with existing members.
  • Like the SafeHandleProcess methods (and unlike the existing Process.WaitForExit methods) these methods do not wait for the EOF to have been received on a standard output and error when those are redirected.
  • Similar members could be added for ExitCode. Or, without these members, the user can get the ExitCode from the ProcessExitStatus.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions