TDStack.cs

Custom Dynamic Concurrent Stack Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class TDStack<T> : IEnumerable<T>
{
    private          T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public TDStack(int sizeHint)
    {
        if (sizeHint < 4)
            throw new Exception("Size must be greater than or equal to 4.");
        _array = new T[sizeHint];
        _maf   = new MonitorActionFunc();
        Count  = 0;
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public T Pop()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            Interlocked.Decrement(ref Count);
            var TVal = _array[Count];
            _array[Count] = default;
            return TVal;
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
    public void Push(T item)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            if (Count == _array.Length)
                Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *