private void DisposeAll() { BeforeCollect?.Invoke(this, new CollectArgs() { ObjectCount = _objQueue.Count }); #if FINALIZER_CHECK lock (_queueLock) #endif { #if FINALIZER_CHECK ValidateRefCount(); #endif IntPtr obj; Runtime.PyErr_Fetch(out var errType, out var errVal, out var traceback); try { while (!_objQueue.IsEmpty) { if (!_objQueue.TryDequeue(out obj)) { continue; } Runtime.XDecref(obj); try { Runtime.CheckExceptionOccurred(); } catch (Exception e) { var errorArgs = new ErrorArgs { Error = e, }; ErrorHandler?.Invoke(this, errorArgs); if (!errorArgs.Handled) { throw new FinalizationException( "Python object finalization failed", disposable: obj, innerException: e); } } } } finally { // Python requires finalizers to preserve exception: // https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation Runtime.PyErr_Restore(errType.StealNullable(), errVal.StealNullable(), traceback.StealNullable()); } } }
/// <summary> /// Raises the BeforeCollect event. /// </summary> /// <remarks> /// Objects that participate in Garbage Collection should associate a callback within the constructor that calls this function. /// </remarks> /// <param name="e"></param> protected virtual void OnBeforeCollect(IntPtr handle, IntPtr callbackState) { if (null != BeforeCollect) { lock (BeforeCollect) { BeforeCollect.Invoke(this, new BaristaObjectBeforeCollectEventArgs(handle, callbackState)); } } }