当前位置:  开发笔记 > 编程语言 > 正文

如何防止WCF服务进入故障状态?

如何解决《如何防止WCF服务进入故障状态?》经验,为你挑选了6个好方法。

我有一个不应该进入故障状态的WCF服务.如果存在异常,则应记录该异常,并且服务应继续不间断.该服务具有单向操作合同,并且正在从MSMQ中读取消息.

我的问题有两个:

    该服务似乎吞噬了异常/错误,因此我无法对其进行调试.如何让服务公开异常,以便我可以记录或处理它?

    吞下此异常后,服务进入故障状态.如何防止服务进入故障状态?

David d C e .. 28

有关如何处理故障的官方文档如下:

处理异常和错误

了解国家变化

主页面位于频道模型概述

有一个很好的状态图显示事情是如何发生的:

在此输入图像描述



1> David d C e ..:

有关如何处理故障的官方文档如下:

处理异常和错误

了解国家变化

主页面位于频道模型概述

有一个很好的状态图显示事情是如何发生的:

在此输入图像描述



2> Christian.K..:

在WCF跟踪(配置跟踪)中可以看到大多数(如果不是全部)异常,并且最好使用服务跟踪查看器查看跟踪.

显然,这不是你应该在生产环境中全天运行的东西,但无论如何它都有助于排除故障.

除此之外,请注意,根据您使用的SessionMode,单向运行可能无法真正"发射并忘记".如果您为SessionMode.Allowed或甚至SessionMode.Required配置了服务,则单向操作将运行,就好像它根本不是一样(当在netTcpBinding上单独使用时可以观察到这一点).坦率地说,我不知道这是否会改变您可以获得的例外类型,或者当您获得它们时.但是,在任何情况下,如果无法发送请求,您应该获得异常.AFAIK,在服务器端成功启用时,单向"结束".因此,在那之前存在(WCF框架相关)异常的某些地方(可以想到序列化/反序列化).

然后,最好看到这样的框架相关异常(即使IErrorHandler因使用上述跟踪/跟踪查看器在请求/响应流中调用它而无法全部获取它们).



3> Marc Gravell..:

例外将导致代理错误.你不能AFAIK做很多事情:不要引起例外;-p

我有点惊讶的是单向的仍然是造成问题,但对于吞咽中属 L时,有3个方面:

    你在抛出错误吗?或例外?这很重要(应该是"缺点")

    作为一个黑客,您可以启用调试异常消息 - 但请关闭它!

    你在"使用"服务对象吗?我刚刚在这个确切的主题上写博客 ...基本上,你的"使用"可以吞下这个例外.3个选项:

    不要使用"使用"

    子类代理并重写Dispose()

    根据博客包装它


您可以尝试切换到FaultException ,其中T是已发布的错误 - 这可能有所帮助.请注意,关闭代理仍然非常重要; 简单地说,"使用"并不一定能在这个场合做到我们想要的.

4> Rolf Kristen..:

通常,WCF服务托管在ServiceHost中,如果WCF服务失败,则唯一的选择是终止WCF服务并启动新服务.

ServiceHost有一个事件触发器"Faulted",在WCF服务失败时激活:

ServiceHost host = new ServiceHost(new Service.MyService());
host.Faulted += new EventHandler(host_faulted);
host.Open();

可能会导致导致错误的异常,但需要更多工作:

public class ErrorHandler : IErrorHandler
{
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {

    }

    public bool HandleError(Exception error)
    {
        Console.WriteLine("exception");
        return false;
    }
}

public class ErrorServiceBehavior : IServiceBehavior
{
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {

    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        ErrorHandler handler = new ErrorHandler();
        foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
        {
            dispatcher.ErrorHandlers.Add(handler);
        }
    }
}

ServiceHost host = new ServiceHost(new Service.MyService());
host.Faulted += new EventHandler(host_faulted);
host.Description.Behaviors.Add(new ErrorServiceBehavior());
host.Open();

积分http://www.haveyougotwoods.ca/2009/06/24/creating-a-global-error-handler-in-wcf


试过这个但是HandleError方法永远不会被命中,即使我点击了Faulted事件处理程序.

5> David Vidmar..:

关于2)...

诀窍是你应该使用"使用",并且应该总是在抛出异常的代理上调用Abort().文章WCF Gotcha解释了这一切.

我们使用受包含服务调用的文章启发的服务类.这是我项目的示例代码:

ServiceHelper.Use(
    proxy => seasonCodeBindingSource.DataSource = proxy.GetSeasonCodes(brandID);
);

这是ServiceHelper的代码,稍微修改一下.到目前为止,它对我们非常好.

using System;
using System.ServiceModel;

namespace Sportina.EnterpriseSystem.Client.Framework.Helpers
{
    public delegate void UseServiceDelegate(TServiceProxy proxy);

    public static class ServiceHelper where TServiceClient : ClientBase, new() where TServiceInterface : class
    {
        public static void Use(UseServiceDelegate codeBlock)
        {
            TServiceClient proxy = null;
            bool success = false;
            try
            {
                proxy = new TServiceClient();               
                codeBlock(proxy);
                proxy.Close();
                success = true;
            }
            catch (Exception ex)
            {
                Common.Logger.Log.Fatal("Service error: " + ex);                                
                throw;
            }
            finally
            {
                if (!success && proxy != null)
                    proxy.Abort();
            }
        }
    }
}


"WCF Gotcha"帖子的链接已损坏,但我没有足够的代表来编辑它.这是一个很好的链接:http://old.iserviceoriented.com/blog/post/Indisposable+-+WCF+Gotcha+1.aspx.

6> 小智..:

我有一个问题,在ReceiveTimeout异常之后,Channel仍然处于故障状态.这将导致任何后续连接使服务无法使用.

从我的故障状态恢复服务的修复是处理通信通道的Faulted事件:

 channelFactory = new ChannelFactory(endpoint);
 channelFactory.Faulted += OnChannelFaulted;
 var channel = channelFactory.CreateChannel();

然后定义OnChannelFaulted:

 void OnChannelFaulted(object sender, EventArgs e)
 {
     channelFactory.Abort();
 }

注意:我通过代码运行WCF配置,而不是使用Web.config中的绑定.

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有