public void Dispose() { if (!_disposed) { _disposed = true; StandardInput?.Dispose(); StandardOutput?.Dispose(); StandardError?.Dispose(); winpty_free(_handle); StandardInput = null; StandardOutput = null; StandardError = null; _handle = IntPtr.Zero; } }
void IDisposable.Dispose() { if (Disposed) { return; } Disposed = true; using (_process) { if (!_process.HasExited) { // Write "exit" message StandardInput.WriteLine("{\"exit\":0}"); ; } StandardInput.Dispose(); StandardOutput.Dispose(); // Give the STDERR sink thread 5 seconds to finish consuming outstanding buffers _stderrSink.Join(5_000); try { // Give the kernel 5 seconds to clean up after itself if (!_process.WaitForExit(5_000)) { // Kill the child process if needed _process.Kill(); } } catch (InvalidOperationException) { // This means the process had already exited, because it was faster to clean up // than we were to process it's termination. We still re-check if the process has // exited and re-throw if not (meaning it was a different issue). if (!_process.HasExited) { throw; } } } }