简体   繁体   English

WCF,渠道工厂和例外

[英]WCF, channel factory, and exceptions

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

I am consuming my service in my client 我在我的客户端使用我的服务

Service is hosted in IIS 服务托管在IIS中

Client(winforms MDI) is generated using svcutil using /l, /r, /ct, & /n switches 客户端(winforms MDI)使用svcutil使用/ l,/ r,/ ct和/ n开关生成

Service and client both use a MyEntities.dll 服务和客户端都使用MyEntities.dll

I am using nettcp with TransportWithMessageCredential I cache the proxy in the main form 我正在使用nettcp与TransportWithMessageCredential我在主窗体中缓存代理

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 然后我将_proxy传递给任何需要使用它的子表单/插件

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 / catch,例如WCF客户端“使用”块问题的最佳解决方法是什么?

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? 我可以订阅_proxy.InnerChannel.Faulted并在那里清理吗?

Regards 问候

_Eric _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 似乎我已经部分回答了我自己的问题,我为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). 这是非常邪恶的,并且在第11次迭代开始时得到了超时错误,这是我的服务的最大用户(10)。 Does this mean that someone can implement any wcf client and open as many channels as the wcf server will allow? 这是否意味着有人可以实现任何wcf客户端并打开与wcf服务器允许的一样多的通道?

I did find that this gave me the expected results and completed all 500 iterations 我确实发现这给了我预期的结果并完成了所有500次迭代

  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? 我现在的问题是,我可以在_proxy.InnerChannel.Faulted事件中进行casttochannel,关闭和处理,或者对于每次调用我只是将其包装在try中然后捕获超时/ comm / fault异常,让代理处理但是处理通道? If the later is the case is there a way to encapsulate this? 如果后者是这种情况有没有办法封装这个?

Regards 问候

_Eric _Eric

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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