Object pool pattern for asynchronous socket operations
Because you don't change 

private int _size;
private Func&lt;T&gt; _factory;
private Stack&lt;T&gt; _cache;


private SpinLock _spinLock; //Use Queue&lt;T&gt; for first-in-first-out (FIFO)

you should make them readonly.  

Correction after the comment of t3chb0t:  

Don't make the SpinLock readonly. Further clarification: https://stackoverflow.com/a/9235028/2655508  


  The underlying problem is that the C# compiler creates a copy of a readonly value type field when you call a non-static method on it and executes that method on the copy - because the method could have side effects that change the value of the struct - which is not allowed for readonly fields. 





private T RentFromCache()
{
    var cache = _cache;

    if (cache.Count &gt; 0)
    {
        T instance = _cache.Pop();

        if (instance != null)
        {
            return instance;
        }
    }

    return CreateInstance();
}  



Here you are using var cache only for checking its Count property. I don't see a reason to not use the class level _cache directly. Using the class level variable directly won't confuse the reader of the code. The same applies to ReturnToCache() as well.