Skip to content

Commit 1bb5fbb

Browse files
committed
Avoid 1-2 first chance exceptions on out of order disposal
Disposing of a marshaled object throws when the underlying connection has already been disposed of. These exceptions appear to be innocuous but they are at least false causes for alarm when the program is run under a debugger. The fix is to arrange to skip when we can predict the exception.
1 parent eefa509 commit 1bb5fbb

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/StreamJsonRpc/Reflection/MessageFormatterRpcMarshaledContextTracker.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,16 @@ internal MarshalToken GetToken(
346346
MethodNameTransform = mn => Invariant($"$/invokeProxy/{token.Value.Handle}/{options.MethodNameTransform(mn)}"),
347347
OnDispose = token.Value.Lifetime == MarshalLifetime.Call ? null : delegate
348348
{
349-
// Only forward the Dispose call if the marshaled interface derives from IDisposable.
350-
if (typeof(IDisposable).IsAssignableFrom(interfaceType))
349+
if (!this.jsonRpc.IsDisposed)
351350
{
352-
this.jsonRpc.NotifyAsync(Invariant($"$/invokeProxy/{token.Value.Handle}/{options.MethodNameTransform(nameof(IDisposable.Dispose))}")).Forget();
353-
}
351+
// Only forward the Dispose call if the marshaled interface derives from IDisposable.
352+
if (typeof(IDisposable).IsAssignableFrom(interfaceType))
353+
{
354+
this.jsonRpc.NotifyAsync(Invariant($"$/invokeProxy/{token.Value.Handle}/{options.MethodNameTransform(nameof(IDisposable.Dispose))}")).Forget();
355+
}
354356

355-
this.jsonRpc.NotifyWithParameterObjectAsync("$/releaseMarshaledObject", new { handle = token.Value.Handle, ownedBySender = false }).Forget();
357+
this.jsonRpc.NotifyWithParameterObjectAsync("$/releaseMarshaledObject", new { handle = token.Value.Handle, ownedBySender = false }).Forget();
358+
}
356359
},
357360
},
358361
token.Value.Handle);

test/StreamJsonRpc.Tests/MarshalableProxyTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,15 @@ public async Task IMarshalable_MarshaledBackAndForth()
585585
Assert.Same(this.server.ReturnedMarshalable, this.server.ReceivedProxy);
586586
}
587587

588+
[Fact]
589+
public async Task MarshableDisposedAfterConnection()
590+
{
591+
IMarshalable? proxyMarshalable = await this.client.GetMarshalableAsync().WithCancellation(this.TimeoutToken);
592+
Assert.NotNull(proxyMarshalable);
593+
this.clientRpc.Dispose();
594+
proxyMarshalable.Dispose();
595+
}
596+
588597
[Fact]
589598
public async Task IMarshalable_MarshaledAndForwarded()
590599
{

0 commit comments

Comments
 (0)