protected override void Dispose(bool disposing) { if (ExternallyOwned) { ThrowHelper.ThrowNotSupportedException(); } if (disposing) { var pool = Pool; if (pool != null) { pool.ReturnInternal(this, clearMemory: !TypeHelper <T> .IsPinnable); // pool calls Dispose(false) if a bucket is full return; } // not pooled, doing finalization work now GC.SuppressFinalize(this); } // Finalization AtomicCounter.Dispose(ref CounterRef); Debug.Assert(!_isPooled); _poolIdx = default; // we still could add this to the pool of free pinned slices that are backed by an existing slab var pooledToFreeSlicesPool = _slicesPool.Return(this); if (pooledToFreeSlicesPool) { return; } var array = Interlocked.Exchange(ref _array, null); if (array != null) { ClearAfterDispose(); Debug.Assert(_handle.IsAllocated); #pragma warning disable 618 _slab.Decrement(); _handle.Free(); #pragma warning restore 618 } else { ThrowDisposed <ArrayMemorySlice <T> >(); } Debug.Assert(!_handle.IsAllocated); }
protected override void Dispose(bool disposing) { if (_externallyOwned) { ThrowHelper.ThrowNotSupportedException(); } EnsureNotRetainedAndNotDisposed(); // disposing == false when finalizing and detected that non pooled if (disposing) { TryReturnThisToPoolOrFinalize(); } else { Debug.Assert(!_isPooled); _pool = null; // we still could add this to the pool of free pinned slices that are backed by an existing slab var pooledToFreeSlicesPool = _slicesPool.Return(this); if (pooledToFreeSlicesPool) { return; } Counter.Dispose(); AtomicCounterService.ReleaseCounter(Counter); ClearAfterDispose(); // destroy the object and release resources var array = Interlocked.Exchange(ref _array, null); if (array != null) { Debug.Assert(_handle.IsAllocated); #pragma warning disable 618 _slab.Decrement(); _handle.Free(); #pragma warning restore 618 } else { ThrowDisposed <ArrayMemory <T> >(); } Debug.Assert(!_handle.IsAllocated); } }