Question

I am refactoring a large programm which does inter-process communication via wcf. Since the client has direct access to the service-interface a channelfactory is used to create channels, so that no extra client-service-stubs are needed. Communication consists of many big messages that are requested with high-frequency (NetTcpBinding is currently used, I am considering a switch to NetNamedPipeBinding).

My question is about the difference between creating/closing the channel vs. creating/closing the channelfactory. To be more precise: The channelfactory creates a channel. Now, in relation to an individual request: Should I create and close the channelfactory and with this also the channel in relation to an individual request (see solution no. 2) or is it more secure/better in terms of performance to only create/close the channel in relation to an individual request and leave the channelfactory open for multiple requests (see solution no. 1).

1)

//set up the channel factory right when I start the whole applicaton
ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>();

//call this trillion of times over time period of hours whenever I want to make a request to the service; channel factory stays open for the whole time
try
{
    IMyService myService = cf.CreateChannel();
    var returnedStuff = myService.DoStuff();
    ((IClientChannel)myService).Close();
}
catch ...

//close the channel factory when I stop the whole application
cf.Close();

2)

//call this trillion of times over time period of hours whenever I want to make a request to the service
try
{
    ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>();
    IMyService myService = cf.CreateChannel();
    var returnedStuff = myService.DoStuff();
    cf.Close();
}
catch ...

What are the pratical differences? What is the right way to do it? Are there even better alternatives?

Was it helpful?

Solution

Creating a channel factory can take up to 70ms (In the application I'm working on). Creating channels (from an existing channel factory is relatively fast in comparison). If your client usually communicates with the host using the same credentials, you should consider caching a channelfactory for each service interface that is consumed. You will see significant performance improvements if you do this. In your question, this would more closely relate to the second option you described.

Darin Damitrov did an interesting post on this here:-

creating WCF ChannelFactory<T>

OTHER TIPS

According to http://www.danrigsby.com/blog/index.php/2008/02/26/dont-wrap-wcf-service-hosts-or-clients-in-a-using-statement/

the way you should do this is:

ChannelFactory<IMyService> channelFactory = null;
try
{
    channelFactory =
        new ChannelFactory<IMyService>();
    channelFactory.Open();

    // Do work...

    channelFactory.Close();
}
catch (CommunicationException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (TimeoutException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (Exception)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
    throw;
}

The main reasoning behind this is if you call Dispose() on ChannelFactory that in turn calls Close(), which can throw an exception if the underlying Channel is in the aborted state.

Not a direkt answer to my original question, but I have seen that there is static CreateChannel-method on ChannelFactory that one can use to createchannels. I now use this method to create the channels and, as a result, I don't have to deal with a channelfactory instance anymore. Therefore, I create the clientchannel before every request with the static factorymethod and close it (the channel) afterwards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top