Exception during ExecuteAsync throws Exception that cannot be handled
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp
- Lĩnh vực
- networking
Hướng nghiên cứu
Bắt đầu từ SshCommand.ExecuteAsync và theo dõi chuỗi khởi động từ lúc tạo _tcs, qua _channel.Open() và SendExecRequest(...), sau đó kiểm tra cách Dispose() xử lý một task chưa hoàn tất. Xác minh hành vi khi xảy ra ngoại lệ trong quá trình khởi động và đảm bảo lỗi được trả về hoặc không còn task faulted ẩn nào.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
SshCommand.ExecuteAsync appears to have a race during command startup.
In the current implementation, _tcs is created before _channel.Open() and _channel.SendExecRequest(...) are called:
_tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
_userToken = cancellationToken;
_channel.DataReceived += Channel_DataReceived;
_channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
_channel.RequestReceived += Channel_RequestReceived;
_channel.Closed += Channel_Closed;
_channel.Open();
_ = _channel.SendExecRequest(CommandText);
return _tcs.Task;
If _channel.Open() or _channel.SendExecRequest(...) throws synchronously due to a connection/session teardown, the method exits before returning _tcs.Task.
If the caller uses the command in a using block, disposal may then execute while _tcs.Task is still incomplete:
if (_tcs is { Task.IsCompleted: false } tcs)
{
_ = tcs.TrySetException(new ObjectDisposedException(GetType().FullName));
}
This can produce a faulted task that was never returned to the caller and therefore can never be awaited or observed. Later, that can surface via TaskScheduler.UnobservedTaskException.
Expected behavior
If command startup fails after _tcs has been created, the failure should not leave behind an orphaned faulted task.
Possible acceptable outcomes:
- ExecuteAsync returns a faulted task, or
- ExecuteAsync catches startup exceptions after _tcs creation, completes _tcs accordingly, and returns it, or
- startup is arranged so no internal task exists before all synchronous failure points have passed.
Actual behavior
Under transient network/session failure, a caller can observe:
- a synchronous exception from ExecuteAsync, and later
- an unrelated TaskScheduler.UnobservedTaskException caused by the internal _tcs.Task being faulted during Dispose() without ever having been returned.
Observed trigger
In our case this happened around network loss / socket failure. We saw a preceding socket error similar to:
System.Net.Sockets.SocketException: A socket operation was attempted to an unreachable network
That seems consistent with the session being torn down while a command is being started.
Suggested fix direction
Wrap the startup section after _tcs creation in a try/catch, and ensure that any exception either:
- completes _tcs and returns _tcs.Task, or
- resets internal state so no hidden faulted task remains.
A minimal fix would likely be around the section between _tcs = new TaskCompletionSource(...) and return _tcs.Task.
- Ngôn ngữ chính
- C#
- Star
- 4.4k
- Fork
- 993
- Merge trung bình
- 9 ngày 21 giờ
- Pull request đã merge (30 ngày)
- 1
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của sshnet/SSH.NET
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
-
Using SshClient on Linux under Wine throws System.Security.Cryptography.CryptographicException Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 67/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
-
sshnet/SSH.NET#1795 · 1 bình luận · 1 reaction · 2 người được giao ·
Tất cả issue của sshnet/SSH.NET
Issue tương tự
-
bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 75/100
sillsdev/languageforge-lexbox#2665 ·
-
bug documentation frontend
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
azurenoops/spin_agent#975 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
SubtitleEdit/subtitleedit#15108 · 1 bình luận ·