使用NamedPipe WCF服务时CommunicationObjectFaulted

lys*_*cid 4 .net c# wcf named-pipes

我们的.NET应用程序使用2个AppDomains.辅助域需要访问在主应用程序域中创建的Logger对象.

此记录器通过具有命名管道绑定的WCF服务公开.

这就是我为这项服务创建"客户"的方式:

        private void InitLogger()
        {    
            if (loggerProxy != null)
            {
                Logger.Instance.onLogEvent -= loggerProxy.Log;
            }

            // Connect to the logger proxy.
            var ep = new EndpointAddress("net.pipe://localhost/app/log");
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);

            //Logger.Debug("Creating proxy to Logger object.");
            var channelFactory = new ChannelFactory<ILogProvider>(binding, ep);

            loggerProxy = channelFactory.CreateChannel();
            channelFactory.Faulted += (sender, args) => InitLogger();
            channelFactory.Closed += (sender, args) => InitLogger();

            Logger.Instance.onLogEvent += loggerProxy.Log;
        }
Run Code Online (Sandbox Code Playgroud)

最近我们得到随机的CommunicationObjectFaultedException - 我想这是因为频道超时或由于某些其他原因导致我失踪.

这就是我添加了ClosedFaulted事件的处理的原因,这些事件似乎无法正常工作(也许我没有正确使用它们).

编辑:这些事件在建议的Factory对象上,因此这解释了为什么它们没有被引发.

我的问题是 - 我怎样才能避免这些错误?

我们的方案是我们需要在整个应用程序的生命周期内始终保持此通道的开放,并且始终需要访问此Logger服务,并且在任何情况下都不应超时.

处理这种情况有安全做法吗?

Chr*_*son 6

您的代码当前正在处理ChannelFactory引发的Closed和Faulted事件,但是您需要担心的是Channel本身的状态.

ChannelFactory是一个人工制品,它将WCF服务合同的转换封装到通道运行时的实例中:一旦您成功创建了channel(loggerProxy),ChannelFactory的关闭不会影响通过通道的通信 - 事件你正在倾听与你的问题无关.

Channel的状态转换为Closed或Faulted将不会被注意到此代码,结果是它们将在Logger.Instance中显示为loggerProxy.Log调用时抛出的异常,并且您尝试记录的事件将丢失.

loggerProxy.Log您应该考虑注册实现异常处理程序的包装函数,并重试对loggerProxy.Log的调用循环,而不是直接注册为事件处理程序.应在异常处理程序中关闭现有通道(如果失败,中止),以确保它已正确处置.重试循环应重新初始化频道并再次尝试呼叫.