views:

653

answers:

2

Using vs2008, vb.net, C#, fw 3.5

I am consuming my service in my client

Service is hosted in IIS

Client(winforms MDI) is generated using svcutil using /l, /r, /ct, & /n switches

Service and client both use a MyEntities.dll

I am using nettcp with TransportWithMessageCredential I cache the proxy in the main form

if  Membership.ValidateUser(UsernameTextBox.Text, PasswordTextBox.Text)
    _proxy = new MyServiceClient
    _proxy.ClientCredentials.UserName.UserName = "username"
    _proxy.ClientCredentials.UserName.Password = "password"

I then pass the _proxy around to any child forms/plugins that need to use it ex

List(of Orders) =  _proxy.ChannelFactory.CreateChannel.GetOrders(customer)

Everything is working great but my questions are this:

What happens to the channels after the call? Are they magically disposed?

How could I monitor this, with a profiler?

Is there a way I can have error handling in one place, or do I need to place try/catch in every call like http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

Could I subscribe to the _proxy.InnerChannel.Faulted and do that clean up there?

Regards

_Eric

A: 

Additional test results/notes

It seems I have partially answered my own question, I ran this a loop for 500 X

 List(of Orders) =  _proxy.ChannelFactory.CreateChannel.GetOrders(customer)

This is very evil, and on the start of the 11th iteration got a timeout error, which is the max users of my service(10). Does this mean that someone can implement any wcf client and open as many channels as the wcf server will allow?

I did find that this gave me the expected results and completed all 500 iterations

  Dim channel = _proxy.ChannelFactory.CreateChannel
     e.result = Channel.GetOrders(customer)
     Dim Ich = DirectCast(channel, ServiceModel.IClientChannel)
     Ich.Close()
     Ich.Dispose()

My question is now can I casttochannel, close and dispose inside the _proxy.InnerChannel.Faulted event or for every call I make just wrap it in a try and then catch timeout/comm/fault exceptions leaving the proxy be but disposing of the channel? If the later is the case is there a way to encapsulate this?

Regards

_Eric

Eric
+1  A: 

I use to do two different things, depending on the use case:

  • In a client scenario where I know only one instance of the channel is used at a time, I lazy-create a channel, and re-use the created instance. In case it is faulted, closed, or disposed, the channel is re-created.
  • In scenarios where multiple channels can be requested at the same time, I think it is the best to do the exception handling dance. In order to avoid code bloat, you can centralize it into a method that accepts a delegate for the actual work that it done, so that it form a write-once exoskeleton around your payload code.
GreenIcicle
I agree with the "exception handling dance". I ended up using the Exception Handling WCF Proxy Generator from codeplex.
Eric