我有一个自主托管的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="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.IServiceBehaviorImplement 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服务?
发布评论