diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index d028c4fbd..1e8d4dbae 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -143,6 +143,13 @@ public virtual void DisposePeer (IJavaPeerable value) if (value == null) throw new ArgumentNullException (nameof (value)); + if (!value.PeerReference.IsValid) + return; + + RemovePeer (value); + + value.Disposed (); + var h = value.PeerReference; if (!h.IsValid) return; @@ -155,8 +162,6 @@ void DisposePeer (JniObjectReference h, IJavaPeerable value) if (disposed) throw new ObjectDisposedException (GetType ().Name); - value.Disposed (); - RemovePeer (value); var o = Runtime.ObjectReferenceManager; if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine ("Disposing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3} Java.Type={4}", diff --git a/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs b/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs index 92133e194..bf65b4b84 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs @@ -185,6 +185,14 @@ public void CrossThreadSharingRequresRegistration () o.ToString (); o.Dispose (); } + + [Test] + public void NestedDisposeInvocations () + { + var value = new MyDisposableObject (); + value.Dispose (); + value.Dispose (); + } } class JavaObjectWithNoJavaPeer : JavaObject { @@ -215,5 +223,25 @@ protected override void Dispose (bool disposing) OnFinalized (); } } + + [JniTypeSignature ("java/lang/Object")] + class MyDisposableObject : JavaObject { + bool _isDisposed; + + public MyDisposableObject () + { + } + + protected override void Dispose (bool disposing) + { + if (_isDisposed) { + return; + } + _isDisposed = true; + if (this.PeerReference.IsValid) + this.Dispose (); + base.Dispose (disposing); + } + } }