diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs
index a57d5a1e7..dab919552 100644
--- a/src/Renci.SshNet/Session.cs
+++ b/src/Renci.SshNet/Session.cs
@@ -1788,9 +1788,17 @@ internal static string ToHex(byte[] bytes)
/// when the value of is obtained. To workaround this issue
/// we synchronize reads from the .
///
+ ///
+ /// We assume the socket is still connected if the read lock cannot be acquired immediately.
+ /// In this case, we just return without actually waiting to acquire
+ /// the lock. We don't want to wait for the read lock if another thread already has it because
+ /// there are cases where the other thread holding the lock can be waiting indefinitely for
+ /// a socket read operation to complete.
+ ///
///
private bool IsSocketConnected()
{
+#pragma warning disable S2222 // Locks should be released on all paths
lock (_socketDisposeLock)
{
if (!_socket.IsConnected())
@@ -1798,12 +1806,22 @@ private bool IsSocketConnected()
return false;
}
- lock (_socketReadLock)
+ if (!Monitor.TryEnter(_socketReadLock))
+ {
+ return true;
+ }
+
+ try
{
var connectionClosedOrDataAvailable = _socket.Poll(0, SelectMode.SelectRead);
return !(connectionClosedOrDataAvailable && _socket.Available == 0);
}
+ finally
+ {
+ Monitor.Exit(_socketReadLock);
+ }
}
+#pragma warning restore S2222 // Locks should be released on all paths
}
///