insipid
insipid

Reputation: 3308

Is it possible for a WCF channel to fault right after checking the state (single thread)?

I have been handing the closing and aborting of channels this way:

public async Task<MyDataContract> GetDataFromService()
{
    IClientChannel channel = null;
    try
    {
        IMyContract contract = factory.CreateChannel(address);
        MyDataContract returnValue = await player.GetMyDataAsync();
        channel = (IClientChannel);
        return returnValue;
    } 
    catch (CommunicationException)
    {
       // ex handling code
    } 
    finally
    {
        if (channel != null)
        {
            if (channel.State == CommunicationState.Faulted)
            {
                channel.Abort();
            }
            else
            {
                channel.Close();
            }
         }
    }
}

Assume only a single thread uses the channel. How do we know the channel will not fault right after checking the state? If such a thing were to happen, the code would try to Close() and Close() will throw an exception in the finally block. An explanation about why this is safe/unsafe and examples of a better, safer way would be appreciated.

Upvotes: 5

Views: 624

Answers (1)

Haney
Haney

Reputation: 34832

Yes, the state is a "snapshot" of the current state when you get it. In the time between when you access the CommunicationState and when you go to make a logical decision based on it, the state can have easily changed. A better WCF pattern is:

try
{
    // Open connection
    proxy.Open();

    // Do your work with the open connection here...
}
finally
{
    try
    {
        proxy.Close();
    }
    catch
    {
        // Close failed
        proxy.Abort();
    }
}

In this way you don't rely on the state in order to make decisions. You try to do the most likely thing (a healthy close) and if that fails (which it will when the CommunicationState is Faulted), you call Abort to ensure proper cleanup.

Upvotes: 2

Related Questions