[API Proposal]: Change existing Process class behaviour to retain important properties after Process Exit
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Background and motivation
It is well documented that the Process class has usability issues, among other things. Some of these usability issues come from behaviours that are effectively hidden landmines in the ``Process`` class, that one has to know to avoid in order to not have Exceptions thrown.
Several of these are caused by the Process class not retaining important properties after a Process Exits such as ``StartTime``, ``Id``, and ``StartInfo``. Some others are caused by unhelpful current default values like ``EnableRaisingEvents`` defaulting to ``false``.
Whilst these could be considered behavioral breaking changes, they would really help address common problems with the Process class without being a breaking API surface/code change.
I am aware of [this proposal](https://github.com/dotnet/runtime/issues/123959) to provide easy to use and reliable APIs for Process but this addresses different issues and these behaviour changes should apply to the existing ``Process`` class and not be delegated to the new ``ChildProcess`` API.
### API Proposal
```csharp
namespace System.Collections.Generic;
public class Process : IDisposable
{
// Set EnableRaisingEvents to true by default
public bool EnableRaisingEvents {get; set;} = true;
}
```
Non public facing API changes:
* Keep the Process ``StartTime`` property accessible after Process Exit without throwing an Exception
* Keep the Process ``Id`` property, ``ProcessName``, and ``StartInfo`` available to access without throwing an Exception - These are managed resources and do not need to be manually disposed of after a Process Exits.
### API Usage
```csharp
// Create the ProcessStartInfo
ProcessStartInfo startInfo = new(){
FileName = "ExecutableFilePath",
Arguments = "args"
};
Process process = new(startInfo);
process.Exited += OnExited;
process.Start();
await Process.WaitForExitAsync();
// Use currently inaccessible properties after Process exits
TimeSpan duration = process.EndTime - process.StartTime;
Console.WriteLine($"{process.StartInfo.FileName} was run with with Id of {process.Id}");
Console.WriteLine($"Process with Id of {process.Id }ran for {duration.TotalMilliseconds}ms");
private void OnExited(object? sender, EventArgs e)
{
// Do exit related cleanup or run other code here
}
```
This code with the existing Process class behavioiurs would cause an exception to be thrown.
### Alternative Designs
_No response_
### Risks
Consumers may be unaware of behaviour changes if not properly communicated - This could be added to the list of changes to the .NET SDK if adopted.
Contributor guide
Assessment
This issue has not been assessed yet.