Skip to content

Commit 8c34f03

Browse files
authored
Merge pull request #1220 from microsoft/OutOfOrderMarshalledObjectDisposal
Avoid 1-2 first chance exceptions on out of order disposal
2 parents eefa509 + 1bb5fbb commit 8c34f03

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)