Pool of two objects for a web service
I have plenty of things to say here.. 


You should apply separation of concerns by isolating the pooling behavior from the logic of the webmethod itself.
you might want to create both instances at startup
blocking inside the web methods will seriously limit throughput, consider using async methods
What happens if there is an exception and you don't release the mutex?
The pooling can be implemented much simpler using higher level concurrency features, for example a BlockingCollection:




public class ObjectPool&lt;T&gt; 
{
    private readonly BlockingCollection&lt;Lazy&lt;T&gt;&gt; _pool;

    public ObjectPool(int size, Func&lt;T&gt; constructor)
    {
        var resources = Enumerable.Repeat(new Lazy&lt;T&gt;(constructor), size);
        var stack = new ConcurrentStack&lt;Lazy&lt;T&gt;&gt;(resources);
        _pool = new BlockingCollection&lt;Lazy&lt;T&gt;&gt;(stack);
    }

    public IDisposable Aquire(out T resource)
    {
        Lazy&lt;T&gt; lazy = _pool.Take();
        resource = lazy.Value;
        return new Disposable(() =&gt; _pool.Add(lazy));
    }

    public class Disposable : IDisposable
    {
        private readonly Action _dispose;

        public Disposable(Action dispose)
        {
            _dispose = dispose;
        }

        public void Dispose()
        {
            _dispose.Invoke();
        }
    }
}


The call to Aquire will block until an item is available in the pool, it's very important to call Dispose on the returned object, this will release the resouce back into the pool. You can use try/finally or a using statement:

    private static readonly ObjectPool&lt;Random&gt; pool 
        = new ObjectPool&lt;Random&gt;(2, () =&gt; new Random());

    static int CalculateRandomNumber()
    {
        using (pool.Aquire(out var rnd))
        {
            return rnd.Next();
        }
    }


Notice how a Stack is used in combination with Lazy. This ensures that you will never create more instances than are in use at the same time.