diff --git a/README.md b/README.md index 997047b..302c315 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,7 @@ class SshClient : IDisposable // Not usable with AutoReconnect. // A connection must be established before calling this method. - // Throws if the connection was closed for another reason than explicit close by the user. - Task DisconnectedAsync(CancellationToken cancellationToken = default); + CancellationToken Disconnected { get; } Task ExecuteAsync(string command, CancellationToken cancellationToken); Task ExecuteAsync(string command, ExecuteOptions? options = null, CancellationToken cancellationToken = default); diff --git a/src/Tmds.Ssh/SshClient.cs b/src/Tmds.Ssh/SshClient.cs index 03bc27b..be088c1 100644 --- a/src/Tmds.Ssh/SshClient.cs +++ b/src/Tmds.Ssh/SshClient.cs @@ -89,13 +89,16 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default) await GetSessionAsync(cancellationToken, explicitConnect: true).ConfigureAwait(false); } - public Task DisconnectedAsync(CancellationToken cancellationToken = default) + public CancellationToken Disconnected { - SshSession session = GetConnectedSesion(cancellationToken); - return session.DisconnectedAsync(cancellationToken); + get + { + SshSession session = GetConnectedSesion(); + return session.ConnectionClosed; + } } - private SshSession GetConnectedSesion(CancellationToken cancellationToken, [CallerMemberNameAttribute]string? callerMethod = null) + private SshSession GetConnectedSesion([CallerMemberNameAttribute]string? callerMethod = null) { if (_autoReconnect) { diff --git a/src/Tmds.Ssh/SshSession.cs b/src/Tmds.Ssh/SshSession.cs index 5d35fff..4be2c63 100644 --- a/src/Tmds.Ssh/SshSession.cs +++ b/src/Tmds.Ssh/SshSession.cs @@ -98,33 +98,6 @@ public async Task ConnectAsync(TimeSpan connectTimeout, CancellationToken ct = d await task; } - public async Task DisconnectedAsync(CancellationToken cancellationToken) - { - Task? runningConnectionTask = null; - lock (_gate) - { - // Throw if a user has Disposed before calling this method. - ThrowIfDisposed(); - - runningConnectionTask = _runningConnectionTask; - } - - if (runningConnectionTask is null) - { - Debug.Assert(false); // this method shouldn't ever get called if we never connected. - ThrowNeverConnected(); - } - await runningConnectionTask.WaitAsync(cancellationToken); - - // Don't throw if the connection was closed due to an explicit close by the user. - if (_abortReason == DisposedException) - { - return; - } - - ThrowNewConnectionClosedException(); - } - private async Task EstablishConnectionAsync(CancellationToken ct) { Debug.Assert(_settings is not null); diff --git a/test/Tmds.Ssh.Tests/ConnectTests.cs b/test/Tmds.Ssh.Tests/ConnectTests.cs index 315a4b9..49c160c 100644 --- a/test/Tmds.Ssh.Tests/ConnectTests.cs +++ b/test/Tmds.Ssh.Tests/ConnectTests.cs @@ -461,62 +461,53 @@ public async Task SshConfig_Options() } [Fact] - public async Task DisconnectedAsync() + public async Task Disconnected() { using var client = await _sshServer.CreateClientAsync(); - Task disconnectedTask = client.DisconnectedAsync(); + CancellationToken disconnected = client.Disconnected; client.Dispose(); - await disconnectedTask; + Assert.True(disconnected.IsCancellationRequested); } [Fact] - public async Task DisconnectedAsync_WithError() + public async Task Disconnected_WithError() { using var client = await _sshServer.CreateClientAsync(); - Task disconnectedTask = client.DisconnectedAsync(); + CancellationToken disconnected = client.Disconnected; client.ForceConnectionClose(); - await Assert.ThrowsAsync(() => disconnectedTask); + Assert.True(disconnected.IsCancellationRequested); + Assert.True(client.Disconnected.IsCancellationRequested); } [Fact] - public async Task DisconnectedAsync_RequiresConnect() + public async Task Disconnected_RequiresConnect() { using var client = await _sshServer.CreateClientAsync(connect: false); - await Assert.ThrowsAsync(() => client.DisconnectedAsync()); + Assert.Throws(() => client.Disconnected); } [Fact] - public async Task DisconnectedAsync_NotWhenAutoReconnect() + public async Task Disconnected_NotWhenAutoReconnect() { using var client = await _sshServer.CreateClientAsync(configure: settings => settings.AutoReconnect = true); - await Assert.ThrowsAsync(() => client.DisconnectedAsync()); + Assert.Throws(() => client.Disconnected); } [Fact] - public async Task DisconnectedAsync_NotAfterDispose() + public async Task Disconnected_NotAfterDispose() { using var client = await _sshServer.CreateClientAsync(); client.Dispose(); - await Assert.ThrowsAsync(() => client.DisconnectedAsync()); - } - - [Fact] - public async Task DisconnectedAsync_CanCancel() - { - using var client = await _sshServer.CreateClientAsync(); - - var cts = new CancellationTokenSource(50); - - await Assert.ThrowsAnyAsync(() => client.DisconnectedAsync(cts.Token)); + Assert.Throws(() => client.Disconnected); } }