File tree Expand file tree Collapse file tree 2 files changed +28
-2
lines changed
Expand file tree Collapse file tree 2 files changed +28
-2
lines changed Original file line number Diff line number Diff line change @@ -54,6 +54,7 @@ public partial class CopilotSession : IAsyncDisposable
5454 private SessionHooks ? _hooks ;
5555 private readonly SemaphoreSlim _hooksLock = new ( 1 , 1 ) ;
5656 private SessionRpc ? _sessionRpc ;
57+ private int _isDisposed ;
5758
5859 /// <summary>
5960 /// Gets the unique identifier for this session.
@@ -560,8 +561,24 @@ await InvokeRpcAsync<object>(
560561 /// </example>
561562 public async ValueTask DisposeAsync ( )
562563 {
563- await InvokeRpcAsync < object > (
564- "session.destroy" , [ new SessionDestroyRequest ( ) { SessionId = SessionId } ] , CancellationToken . None ) ;
564+ if ( Interlocked . Exchange ( ref _isDisposed , 1 ) == 1 )
565+ {
566+ return ;
567+ }
568+
569+ try
570+ {
571+ await InvokeRpcAsync < object > (
572+ "session.destroy" , [ new SessionDestroyRequest ( ) { SessionId = SessionId } ] , CancellationToken . None ) ;
573+ }
574+ catch ( ObjectDisposedException )
575+ {
576+ // Connection was already disposed (e.g., client.StopAsync() was called first)
577+ }
578+ catch ( IOException )
579+ {
580+ // Connection is broken or closed
581+ }
565582
566583 _eventHandlers . Clear ( ) ;
567584 _toolHandlers . Clear ( ) ;
Original file line number Diff line number Diff line change @@ -215,4 +215,13 @@ public void Should_Throw_When_UseLoggedInUser_Used_With_CliUrl()
215215 } ) ;
216216 } ) ;
217217 }
218+
219+ [ Fact ]
220+ public async Task Should_Not_Throw_When_Disposing_Session_After_Stopping_Client ( )
221+ {
222+ await using var client = new CopilotClient ( new CopilotClientOptions ( ) ) ;
223+ await using var session = await client . CreateSessionAsync ( ) ;
224+
225+ await client . StopAsync ( ) ;
226+ }
218227}
You can’t perform that action at this time.
0 commit comments