C# - 在基于事件的 WCF 代理中处理故障异常
C# - Handling Fault Exceptions in event-based WCF proxy
我正在使用 Visual Studio 生成的基于事件的代理来使用 WCF 服务。我 运行 遇到一个问题,如果对服务的调用超时,我的应用程序将挂起。服务调用如下:
ServiceClient client = new ServiceClient(binding, endpointAddress);
client.AuthenticateCompleted += (sender, e) =>
{
if (e.Error != null)
throw e.Error;
};
client.AuthenticateAsync(username, password);
浏览了无数其他问题,普遍的共识是任何异常都应该被 WCF 捕获并在上面的 e.Error
中找到。但是,当我的服务超时时,情况并非如此,错误要么为 null,要么在我 运行 的其他一些测试中,应用程序在代码中到达这一点之前就崩溃了。另一位用户建议将上述代码包装在 try/catch 块中,但是,这样做也无法捕获异常。
我也试过在完成处理程序中放置 try/catch 块,以及许多其他更复杂的方法,这些方法超出了问题的范围,因为我真的只需要以最简单的形式工作继续。
可能还值得一提的是,虽然其中许多故障发生在实时服务上,打开、关闭、发送和接收超时各为 30 秒,但我也一直在尝试通过以下方式测试对问题的修复将超时时间降至 <1 秒。我认为这仍然会产生超时异常并且不会导致任何其他问题,但我不是 100% 确定。
我也没有创建 WCF 服务,因此如果需要在服务器端执行特定操作以将异常抛回客户端,则可能缺少此元素。如果是这种情况,有什么办法解决这个问题吗?
事实证明错误是由 IService.EndMethodName
方法引发的,该方法无法通过 Visual Studio 生成的 class 访问。
相反,我决定直接访问频道,这样我可以更好地控制事情。最终实现如下所示(IService 是 Visual Studio 生成的接口):
ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, endpointAddress);
// CreateChannel may not require any parameters outside of Mono
IService channel = factory.CreateChannel(endpointAddress);
channel.BeginAuthenticate(new AuthenticateRequest(arg0, arg1), result =>
{
try
{
channel.EndAuthenticate(result);
}
catch(Exception ex)
{
throw;
}
}, channel);
这是最简单的形式,但一般的想法是调用在 try/catch 块内的 AsyncCallback
结束,以便在那里进行任何异常处理。
我正在使用 Visual Studio 生成的基于事件的代理来使用 WCF 服务。我 运行 遇到一个问题,如果对服务的调用超时,我的应用程序将挂起。服务调用如下:
ServiceClient client = new ServiceClient(binding, endpointAddress);
client.AuthenticateCompleted += (sender, e) =>
{
if (e.Error != null)
throw e.Error;
};
client.AuthenticateAsync(username, password);
浏览了无数其他问题,普遍的共识是任何异常都应该被 WCF 捕获并在上面的 e.Error
中找到。但是,当我的服务超时时,情况并非如此,错误要么为 null,要么在我 运行 的其他一些测试中,应用程序在代码中到达这一点之前就崩溃了。另一位用户建议将上述代码包装在 try/catch 块中,但是,这样做也无法捕获异常。
我也试过在完成处理程序中放置 try/catch 块,以及许多其他更复杂的方法,这些方法超出了问题的范围,因为我真的只需要以最简单的形式工作继续。
可能还值得一提的是,虽然其中许多故障发生在实时服务上,打开、关闭、发送和接收超时各为 30 秒,但我也一直在尝试通过以下方式测试对问题的修复将超时时间降至 <1 秒。我认为这仍然会产生超时异常并且不会导致任何其他问题,但我不是 100% 确定。
我也没有创建 WCF 服务,因此如果需要在服务器端执行特定操作以将异常抛回客户端,则可能缺少此元素。如果是这种情况,有什么办法解决这个问题吗?
事实证明错误是由 IService.EndMethodName
方法引发的,该方法无法通过 Visual Studio 生成的 class 访问。
相反,我决定直接访问频道,这样我可以更好地控制事情。最终实现如下所示(IService 是 Visual Studio 生成的接口):
ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, endpointAddress);
// CreateChannel may not require any parameters outside of Mono
IService channel = factory.CreateChannel(endpointAddress);
channel.BeginAuthenticate(new AuthenticateRequest(arg0, arg1), result =>
{
try
{
channel.EndAuthenticate(result);
}
catch(Exception ex)
{
throw;
}
}, channel);
这是最简单的形式,但一般的想法是调用在 try/catch 块内的 AsyncCallback
结束,以便在那里进行任何异常处理。