/// <summary> /// Registers the specified instance with the dictionary. /// </summary> internal static void RegisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero || instance == null) { return; } SKObject objectToDispose = null; instancesLock.EnterWriteLock(); try { if (instances.TryGetValue(handle, out var oldValue) && oldValue.Target is SKObject obj && !obj.IsDisposed) { #if THROW_OBJECT_EXCEPTIONS if (obj.OwnsHandle) { // a mostly recoverable error // if there is a managed object, then maybe something happened and the native object is dead throw new InvalidOperationException( $"A managed object already exists for the specified native object. " + $"H: {handle.ToString ("x")} Type: ({obj.GetType ()}, {instance.GetType ()})"); } #endif // this means the ownership was handed off to a native object, so clean up the managed side objectToDispose = obj; } instances[handle] = new WeakReference(instance); } finally { instancesLock.ExitWriteLock(); } // dispose the object we just replaced objectToDispose?.DisposeInternal(); }