WCF、通道工厂和异常

4

使用vs2008、vb.net、C#和fw 3.5

我在客户端中使用我的服务

服务托管在IIS中

客户端(winforms MDI)使用svcutil生成,使用了/l、/r、/ct和/n开关

服务和客户端都使用MyEntities.dll

我使用TransportWithMessageCredential的nettcp,将代理缓存到主窗体中

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

我将_proxy传递给需要使用它的任何子表单/插件 ex。
List(of Orders) =  _proxy.ChannelFactory.CreateChannel.GetOrders(customer)

一切都运行得很好, 但我的问题是:

通话结束后这些通道会消失吗,还是它们会被神奇地处理掉?

我怎样才能用分析器监视它们?

是否有办法把错误处理放在一个地方, 或者我需要在每个调用中都放置try/catch, 就像WCF客户端`using`块问题的最佳解决方法是什么?

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

我能订阅 _proxy.InnerChannel.Faulted 并且在那里执行清理操作吗?

谢谢

_Eric


对于dispose问题,除非您在代理上调用了dispose,否则代理不会自动被处理。 - pdiddy
频道怎么样?我不想在客户端退出之前处理代理。它会返回到池中吗? - Eric
2个回答

2

根据不同的使用场景,我会采取两种不同的做法:

  • 在客户端场景下,我只知道一次仅使用一个通道实例,则采用懒惰创建通道的方式,并重复使用已创建的实例。如果通道出现故障、关闭或被释放,则重新创建通道。
  • 在多个通道可以同时请求的场景中,我认为最好进行异常处理操作。为了避免代码臃肿,您可以将其集中到一个方法中,并接受委托进行实际工作,以便形成一个围绕您有效载荷代码的写一次外骨骼。

我同意“异常处理舞蹈”的观点。最终我使用了来自codeplex的异常处理WCF代理生成器。 - Eric

1

附加测试结果/注释

看起来我已经部分回答了自己的问题,我运行了一个500次的循环。

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

这非常恶劣,在第11次迭代开始时出现了超时错误,这是我的服务的最大用户数(10)。这是否意味着有人可以实现任何WCF客户端并打开与WCF服务器允许的一样多的通道?

我发现这给了我预期的结果,并完成了所有500次迭代。

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

我的问题是:

我现在能否在 _proxy.InnerChannel.Faulted 事件中进行 casttochannel、关闭和处理,或者每次调用时只需将其包装在 try 中,然后捕获超时/comm/fault 异常,保留代理但处理通道?如果后者成立,是否有一种方法来封装这个操作?

谢谢

_Eric


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接