【发布时间】:2023-03-22 03:51:01
【问题描述】:
我们有一个从 Web 应用程序使用的 WCF 服务。我们使用的客户端是使用 Visual Studio“添加服务引用”选项生成的。由于它是一个网络应用程序,并且由于应用程序的性质可能会导致会话相对较短,我们选择在用户登录时创建客户端实例并在会话期间保留它,然后在会话结束时处理它。
这让我想到了我的问题 - 我们正在尝试确定处理客户端通道进入故障状态的最佳方式。在搜索了一些之后,我们想出了这个:
if(client.State = CommuncationState.Faulted)
{
client = new Client();
}
try
{
client.SomeMethod();
}
catch //specific exceptions left out for brevity
{
//logging or whatever we decide to do
throw;
}
但是,这不起作用,因为至少在我们的情况下,即使服务关闭,客户端也会显示Open 状态,直到您实际尝试使用它进行调用,此时点它然后进入Faulted状态。
所以这让我们做其他事情。我们想出的另一个选择是:
try
{
client.SomeMethod();
}
catch
{
if(client.State == CommunicationState.Faulted)
{
//we know we're faulted, try it again
client = new Client();
try
{
client.SomeMethod();
}
catch
{
throw;
}
}
//handle other exceptions
}
但是那味道。显然,我们可以通过使用新客户端并在每次调用时处理它来避免这种情况。这似乎没有必要,但如果这是正确的方式,那么我想这就是我们会选择的。那么,优雅地处理确定客户端是否处于故障状态然后对其采取措施的最佳方法是什么?我们真的应该为每次通话都获得一个新客户吗?
要记住的另一件事 - 客户端的实例化以及所有这些检查和处理都发生在客户端的包装类中。如果我们按照预期的方式执行此操作,它对应用程序本身是透明的 - 调用和处理来自它们的异常不需要特殊代码。
【问题讨论】:
-
是什么导致客户端进入故障状态?我一直能够让 WCF 服务正常返回故障,并且客户端可以继续处理它的业务。是服务器没有响应还是什么?
-
在这种情况下,我们使用的是 ASP.NET 成员资格,但我们遇到了超出“userIsOnlineTimeWindow”属性的情况。显然在这种情况下,将用户重定向到登录页面是有意义的,但我们正在努力确保我们为可能进入错误状态的任何其他情况做好准备。
标签: c# wcf exception-handling channel faulted