C# - 在基于事件的 WCF 代理中处理错误异常



我正在使用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 生成的类访问。

相反,我决定直接访问该频道,以便对事情有更多的控制权。最终的实现如下所示(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中结束,以在那里执行任何异常处理。

最新更新