如何在发生未处理的错误时停止自托管WCF服务?

问题描述

| 我有一个作为Windows服务运行的自托管WCF服务。对于测试,我将其作为控制台应用程序运行。 我想捕获服务中发生的所有未处理的异常并关闭主机。我想捕获在生成响应时发生的所有非FaultException异常,以及在“空闲模式”下抛出的所有异常-即从某些工作线程中抛出的所有异常。 不幸的是,我既不能通过IErrorHandler(未调用)也不能通过AppDomain.CurrentDomain.UnhandledException(未引发)来处理异常。 有什么线索吗? App.config:
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name=\"TestServiceBahavior\">
          <serviceMetadata httpGetEnabled=\"true\" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration=\"TestServiceBahavior\" name=\"WcfErrorHandling.TestService\">
        <host>
          <baseAddresses>
            <add baseAddress=\"http://localhost:8001/TestService\" />
          </baseAddresses>
        </host>
        <endpoint address=\"\" binding=\"basicHttpBinding\"
          bindingConfiguration=\"\" contract=\"WcfErrorHandling.ITestService\" />
        <endpoint address=\"mex\" binding=\"mexHttpBinding\"
          contract=\"IMetadataExchange\" />
      </service>
    </services>
  </system.serviceModel>
</configuration>
代码:
using System;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

namespace WcfErrorHandling
{
    [ServiceContract]
    interface ITestService
    {
        [OperationContract]
        string SayHello(string param);
    }

    public class TestService : ITestService
    {
        public string SayHello(string param)
        {
            if (param == \"ae\")
                throw new ArgumentException(\"argument exception\");
            if (param == \"fe\")
                throw new FaultException(\"fault exception\");
            return \"hello\";
        }
    }

    public class TestHost : ServiceHost,IErrorHandler
    {
        public TestHost()
            : base(typeof(TestService))
        {
        }

        public void Start()
        {
            AppDomain.CurrentDomain.UnhandledException += 
                (sender,ea) => UnhandledExceptionHandler(ea.ExceptionObject as Exception);

            Open();
            foreach (var channelDispatcher in ChannelDispatchers.OfType<ChannelDispatcher>())
                channelDispatcher.ErrorHandlers.Add(this);
        }

        public void ProvideFault(Exception error,MessageVersion version,ref Message fault)
        {
            // do nothing
        }

        public bool HandleError(Exception error)
        {
            if (!(error is FaultException))
                UnhandledExceptionHandler(error);
            return true;
        }

        private void UnhandledExceptionHandler(Exception ex)
        {
            Close();
            Environment.Exit(1);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var testHost = new TestHost();
            testHost.Start();
            Console.Out.WriteLine(\"Press any key to exit...\");
            Console.ReadKey();
            testHost.Close();
        }
    }
}
    

解决方法

有同样的问题,这为我解决了: 使您的服务实现此接口:
public class MyService : System.ServiceModel.Description.IServiceBehavior
像这样实现它:
    public void AddBindingParameters(System.ServiceModel.Description.ServiceDescription serviceDescription,ServiceHostBase serviceHostBase,System.Collections.ObjectModel.Collection<System.ServiceModel.Description.ServiceEndpoint> endpoints,System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher channel in serviceHostBase.ChannelDispatchers) { channel.ErrorHandlers.Add(new ErrorHandler()); }
    }

    public void Validate(System.ServiceModel.Description.ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
    {
        return;
    }
并添加此类:
public class ErrorHandler : IErrorHandler
{
   bool IErrorHandler.HandleError(Exception error)
    { return true; }
   void IErrorHandler.ProvideFault(Exception error,System.ServiceModel.Channels.MessageVersion version,ref System.ServiceModel.Channels.Message fault)
    { return;  }
}
现在在HandleError上设置一个断点。它将向您显示异常     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...