Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Service Client Lifetime

Tags:

wcf

wcf-client

I have a WPF appliction that uses WCF services to make calls to the server.

I use this property in my code to access the service

private static IProjectWcfService ProjectService
{
    get
    {
        _projectServiceFactory = new ProjectWcfServiceFactory();
        return _projectServiceFactory.Create();
    }
}

The Create on the factory looks like this

    public IProjectWcfService Create()
    {
        _serviceClient = new ProjectWcfServiceClient();

        //ToDo: Need some way of saving username and password 
        _serviceClient.ClientCredentials.UserName.UserName = "MyUsername";
        _serviceClient.ClientCredentials.UserName.Password = "MyPassword";

        return _serviceClient;
    }

To access the service methods I use somethingn like the following.

ProjectService.Save(dto);

Is this a good approach for what I am trying to do? I am getting an errorthat I can't track down that I think may be realted to having too many service client connections open (is this possible?) notice I never close the service client or reuse it.

What would the best practice for WCF service client's be for WPF calling?

Thanks in advance...

like image 476
Burt Avatar asked Mar 14 '10 00:03

Burt


1 Answers

You're on the right track, I'd say ;-)

Basically, creating the WCF client proxy is a two-step process:

  • create the channel factory
  • from the channel factory, create the actual channel

Step #1 is quite "expensive" in terms of time and effort needed - so it's definitely a good idea to do that once and then cache the instance of ProjectWcfServiceFactory somewhere in your code.

Step #2 is actually pretty lightweight, and since a channel between a client and a service can fall into a "faulted state" when an exception happens on the server (and then needs to be re-created from scratch), caching the actual channel per se is less desirable.

So the commonly accepted best practice would be:

  • create the ChannelFactory<T> (in your case: ProjectWcfServiceFactory) once and cache it for as long as possible; do that heavy lifting only once

  • create the actual Channel (here: IProjectWcfService) as needed, before every call. That way, you don't have to worry about checking its state and recreating it as needed

UPDATE: "what about closing the channel?" asks Burt ;-) Good point!!

The acccepted best practice for this is to wrap your service call in a try....catch....finally block. The tricky part is: upon disposing of the channel, things can do wrong, too, so you could get an exception - that's why wrapping it in a using(....) block isn't sufficient.

So basically you have:

IProjectWcfService client = ChannelFactory.CreateChannel();
try
{
   client.MakeYourCall();
}
catch(CommunicationException ce)
{
    // do any exception handling of your own
}
finally
{
    ICommunicationObject comObj = ((ICommunicationObject)client);

    if(comObj.State == CommunicationState.Faulted)
    {
       comObj.Abort();
    }   
    else
    {
       comObj.Close();
    }
}

And of course, you could definitely nicely wrap this into a method or an extension method or something in order not to have to type this out every time you make a service call.

UPDATE:

The book I always recommend to get up and running in WCF quickly is Learning WCF by Michele Leroux Bustamante. She covers all the necessary topics, and in a very understandable and approachable way. This will teach you everything - basics, intermediate topics, security, transaction control and so forth - that you need to know to write high quality, useful WCF services.

Learning WCF http://ecx.images-amazon.com/images/I/41wYa%2BNiPML._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg

The more advanced topics and more in-depth look at WCF will be covered by Programming WCF Services by Juval Lowy. He really dives into all technical details and topics and presents "the bible" for WCF programming.

Programming WCF Services

like image 118
marc_s Avatar answered Dec 13 '22 02:12

marc_s