I have tried to mimic Golang channels in C# and its performance is pretty good compared to golang itself. On my machine, each channel operation of Golang takes ~75 nano-sec and each Chan<T> (in C#) operation takes ~90 nano-sec.Please let me know if this code can be improved in any way.class Chan<T>{    readonly int size;    T[] buffer;    long head = -1;    long tail = -1;    long closed = 0;    public Chan() { this.size = 0; }    public Chan(int size)    {        if (size < 0) throw new ArgumentOutOfRangeException();        this.size = size;        this.buffer = new T[this.size];    }    object headLock = new object();    public bool To(T t)    {        lock (headLock)        {            long localClosed = 0L;            if (tail - head == buffer.Length) SpinWait.SpinUntil(() => (localClosed = Interlocked.Read(ref closed)) > 0 || tail - head < buffer.Length);            if (localClosed > 0) return false;            var newTail = Interlocked.Increment(ref tail);            buffer[newTail % buffer.Length] = t;            return true;        }    }    object tailLock = new object();    public bool From(out T val)    {        lock (tailLock)        {            long localClosed = 0L;            if (tail - head == 0) SpinWait.SpinUntil(() => (localClosed = Interlocked.Read(ref closed)) > 0 || tail - head > 0);            if (localClosed > 0)            {                val = default(T);                return false;            }            var newHead = Interlocked.Increment(ref head);            val = buffer[newHead % buffer.Length];            return true;        }    }    public void Close()    {        Interlocked.Increment(ref closed);    }}
Golang channel in C#
c#;go
Without the select operator, you haven't got Go channels - you've just got buffered queues, which are much easier to implement but much less useful.Also, it's important to allow channels with a zero size buffer - in thatcase the sender should synchronise with the receiver.