简体   繁体   中英

WCF, channel factory, and exceptions

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 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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM