Thread-safe wrapper around WCF ServiceModel.ClientBase subclass I have an ASP.NET application which uses a Service Reference to a (third-party, offsite) payment processor.

The service reference class is generated automatically.
Its implementation is a subclass of ServiceModel.ClientBase, which 
MSDN documents as, "Any instance members are not guaranteed to be thread safe."


Is the following a good implementation of my wrapper class (to be called from my aspx pages), to guarantee that access to the service reference singleton is thread-safe?
Should I prefer to simply make the service reference an instance member of the wrapper class, without any locking? My fear was that would imply more than one concurrent service instance, and I don't know how to test whether the remote server side would handle that successfully.  




class Authorize : IDisposable
{
    private static ServiceSoapClient s_serviceSoap = null;
    private static object s_locker;

    // This method is invoked from Global.Application_Start() in Global.asax.cs
    internal static void Application_Start()
    {
        // ServiceSoapClient derives from ServiceModel.ClientBase&lt;ServiceSoap&gt;
        s_serviceSoap = new ServiceSoapClient();
        s_locker = new object();
    }

    private bool lockWasTaken = false;
    internal Authorize()
    {
        // Emulate C# `lock` statement
        Monitor.Enter(s_locker, ref lockWasTaken);
        // http://stackoverflow.com/questions/2008382/how-to-heal-faulted-wcf-channels
        if (s_serviceSoap.InnerChannel.State ==
           System.ServiceModel.CommunicationState.Faulted)
        {
            s_serviceSoap.Abort();
            s_serviceSoap = new ServiceSoapClient();
        }
    }
    public void Dispose()
    {
        if (lockWasTaken)
            Monitor.Exit(s_locker);
    }

    internal bool IsAlive()
    {
        // delegate to the singleton
        ANetApiResponseType response = s_serviceSoap.IsAlive();
        log(response, "IsAlive");
        return response.resultCode == MessageTypeEnum.Ok;
    }
    // plus other methods which delegate to the singleton
}
The code in the OP seems thread-safe to me, but may not be the best solution.
If the channel has many concurrent users, and if using the channel takes for example 100 msec, then 100 concurrent users would queue for up to 10 seconds before being able to use the (single) channel one after the other. A 10-second delay is unacceptable (web users abandon the session).
If the channel is to a payment processor, authorizing a customer transaction might take longer than 100 msec (not 100++ msec of CPU time for your ASP.NET server, but rather a 100++ msec delay waiting for a network response from the payment processor).
Wenlong Dong's Blog article, &quot;Performance Improvement for WCF Client Proxy Creation in .NET 3.5 and Best Practices&quot; (2007) says,

A common pattern of using ClientBase styled proxies is to perform
creation/disposing on each call:
foreach (string msg in myList)
{
    // You may add try/catch block here ...
    HelloWorldProxy proxy = new HelloWorldProxy(&quot;MyEndpoint&quot;, new EndpointAddress(address)))
    proxy.Hello(msg);
    proxy.Close();
    // Error handling code here ...
}


This article is not ASP.NET-specific, but it states that concurrent instances of a channel are normal.
This article also warns that, creating and destroying proxies can be very expensive, gives advice on how to minimize the cost, mentions a performance improvement (implicit cacheing) made in .NET 3.5, and warns what behaviour (i.e. specifying an endpoint) will disable that cacheing.
A follow-up article titled A Sample for WCF Client Proxy Pooling gives advice on how to implement a pol of proxies.

See also here and here for warnings about how to close and dispose a WCF channel safely:

It should be closed before it's disposed
If there has been a communication error the Close could throw an exception
In an exception is thrown you should call Abort before trying to Dispose the channel