如何在未处理的错误时停止自主托管的WCF服务? [英] How to stop self-hosted WCF service upon unhandled errors?

查看:173
本文介绍了如何在未处理的错误时停止自主托管的WCF服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自主托管的WCF服务作为Windows服务运行。对于测试,我将其作为控制台应用程序运行。



我想捕获服务中发生的所有未处理的异常并关闭主机。我想捕获在产生响应时发生的所有非FaultExceptions,也可以捕获在空闲模式中抛出的所有异常,即从一些工作线程抛出。





任何线索? p>

App.config:

 <?xml version =1.0 encoding =utf-8?> 
< configuration>
< system.serviceModel>
<行为>
< serviceBehaviors>
< behavior name =TestServiceBahavior>
< serviceMetadata httpGetEnabled =true/>
< / behavior>
< / serviceBehaviors>
< / behavior>
< services>
< service behaviorConfiguration =TestServiceBahaviorname =WcfErrorHandling.TestService>
< host>
< baseAddresses>
< add baseAddress =http:// localhost:8001 / TestService/>
< / baseAddresses>
< / host>
< endpoint address =binding =basicHttpBinding
bindingConfiguration =contract =WcfErrorHandling.ITestService/>
< endpoint address =mexbinding =mexHttpBinding
contract =IMetadataExchange/>
< / service>
< / services>
< /system.serviceModel>
< / configuration>

代码:

 使用系统; 
使用System.Linq;
使用System.ServiceModel;
使用System.ServiceModel.Channels;
使用System.ServiceModel.Dispatcher;

命名空间WcfErrorHandling
{
[ServiceContract]
接口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)
抛出新的FaultException(fault exception);
returnhello;

}

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

public void Start()
{
AppDomain.CurrentDomain.UnhandledException + =
(sender,ea)=> ; UnhandledExceptionHandler(ea.ExceptionObject为异常);

Open();
foreach(ChannelDispatchers.OfType&ChannelDispatcher>()中的var channelDispatcher)
channelDispatcher.ErrorHandlers.Add(this);
}

public void ProvideFault(异常错误,MessageVersion版本,ref消息错误)
{
// do nothing
}

public bool HandleError(异常错误)
{
if(!(error is FaultException))
UnhandledExceptionHandler(error);
返回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(按任意键退出...);
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>端点,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(异常错误)
{return true;
void IErrorHandler.ProvideFault(异常错误,System.ServiceModel.Channels.MessageVersion版本,引用System.ServiceModel.Channels.Message错误)
{return; }
}

现在在HandleError上设置一个断点,它会显示异常


I have a self-hosted WCF service that is running as a Windows Service. For the tests, I'm running it as a console application.

I'd like to catch all unhandled exceptions that happen in the service and shutdown the host. I'd like to catch all non FaultExceptions that happen when producing a response, but also all exceptions that are thrown in "idle mode" - i.e. thrown from some worker threads.

Unfortunatelly, I can't handle the exceptions neither by IErrorHandler (not called), nor by AppDomain.CurrentDomain.UnhandledException (not raised).

Any clues?

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>

The code:

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();
        }
    }
}

解决方案

Had the same problem, this solved it for me:

Make your service implement this interface:

public class MyService : System.ServiceModel.Description.IServiceBehavior

Implement it like this:

    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;
    }

And add this class:

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;  }
}

Now set a breakpoint on HandleError.. it will show you the exception

这篇关于如何在未处理的错误时停止自主托管的WCF服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆