From cdbfe21b663d08ba9736178092c367e598e9f1bb Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Wed, 21 Feb 2024 09:30:26 +0800 Subject: [PATCH 1/2] Add `Closed` event to `ShellStream`. Lib consumer could hook to this event to detect if channel is closed by server **in time**. --- src/Renci.SshNet/ShellStream.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Renci.SshNet/ShellStream.cs b/src/Renci.SshNet/ShellStream.cs index 4e53fb16f..339c77b43 100644 --- a/src/Renci.SshNet/ShellStream.cs +++ b/src/Renci.SshNet/ShellStream.cs @@ -44,6 +44,11 @@ public class ShellStream : Stream /// public event EventHandler? ErrorOccurred; + /// + /// Occurs when the channel was closed. + /// + public event EventHandler? Closed; + /// /// Gets a value indicating whether data is available on the to be read. /// @@ -894,6 +899,7 @@ private void Session_Disconnected(object? sender, EventArgs e) private void Channel_Closed(object? sender, ChannelEventArgs e) { Dispose(); + Closed?.Invoke(this, EventArgs.Empty); } private void Channel_DataReceived(object? sender, ChannelDataEventArgs e) From e099036f5aa30276c668ee39bee91041f7d1c2e2 Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Wed, 21 Feb 2024 11:27:06 +0800 Subject: [PATCH 2/2] handle `Closed` event on different thread. No need to block original thread. --- src/Renci.SshNet/ShellStream.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Renci.SshNet/ShellStream.cs b/src/Renci.SshNet/ShellStream.cs index 339c77b43..202311701 100644 --- a/src/Renci.SshNet/ShellStream.cs +++ b/src/Renci.SshNet/ShellStream.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; +using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -899,7 +900,12 @@ private void Session_Disconnected(object? sender, EventArgs e) private void Channel_Closed(object? sender, ChannelEventArgs e) { Dispose(); - Closed?.Invoke(this, EventArgs.Empty); + + if (Closed != null) + { + // Handle event on different thread + ThreadAbstraction.ExecuteThread(() => Closed?.Invoke(this, EventArgs.Empty)); + } } private void Channel_DataReceived(object? sender, ChannelDataEventArgs e)