Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }