示例#1
0
        /// <summary>
        /// Removes the registered instance from the dictionary.
        /// </summary>
        internal static void DeregisterHandle(IntPtr handle, SKObject instance)
        {
            if (handle == IntPtr.Zero)
            {
                return;
            }

            if (instance is ISKSkipObjectRegistration)
            {
                return;
            }

            instancesLock.EnterWriteLock();
            try {
                var existed = instances.TryGetValue(handle, out var weak);
                if (existed && (!weak.IsAlive || weak.Target == instance))
                {
                    instances.Remove(handle);
                }
                else
                {
#if THROW_OBJECT_EXCEPTIONS
                    InvalidOperationException ex = null;
                    if (!existed)
                    {
                        // the object may have been replaced

                        if (!instance.IsDisposed)
                        {
                            // recoverable error
                            // there was no object there, but we are still alive
                            ex = new InvalidOperationException(
                                $"A managed object did not exist for the specified native object. " +
                                $"H: {handle.ToString ("x")} Type: {instance.GetType ()}");
                        }
                    }
                    else if (weak.Target is SKObject o && o != instance)
                    {
                        // there was an object in the dictionary, but it was NOT this object

                        if (!instance.IsDisposed)
                        {
                            // recoverable error
                            // there was a new living object there, but we are still alive
                            ex = new InvalidOperationException(
                                $"Trying to remove a different object with the same native handle. " +
                                $"H: {handle.ToString ("x")} Type: ({o.GetType ()}, {instance.GetType ()})");
                        }
                    }
                    if (ex != null)
                    {
                        if (instance.fromFinalizer)
                        {
                            exceptions.Add(ex);
                        }
                        else
                        {
                            throw ex;
                        }
                    }
#endif
                }
            } finally {
                instancesLock.ExitWriteLock();
            }
        }
示例#2
0
        /// <summary>
        /// Registers the specified instance with the dictionary.
        /// </summary>
        internal static void RegisterHandle(IntPtr handle, SKObject instance)
        {
            if (handle == IntPtr.Zero || instance == null)
            {
                return;
            }

            if (instance is ISKSkipObjectRegistration)
            {
                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();
        }