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 结束,以便在那里进行任何异常处理。