简体   繁体   English

如何在WCF线程中强制未处理的异常使进程崩溃?

[英]How can I force unhandled exceptions in a WCF thread to crash the process?

So here's the scenario: 所以这是场景:

I have a WCF service that has a bunch of FaultContracts defined per operation. 我有一个WCF服务,每个操作定义了一堆FaultContracts。 I would like to arrange it such that if an unhandled exception is thrown in a WCF service thread that does not match a valid FaultContract, it takes down the entire process rather than just the thread. 我想安排它,如果在与有效FaultContract不匹配的WCF服务线程中抛出未处理的异常,它将取消整个进程而不仅仅是线程。 (The reason being that I would like a crash dump that contains the information on the exception, since it didn't match the contract.) (原因是我想要一个包含异常信息的崩溃转储,因为它与合同不匹配。)

Is there any way to do this cleanly? 有没有办法干净利落地做到这一点? The main problem I have is that WCF wants to translate all my exceptions into a client-side fault in order to keep the service running; 我遇到的主要问题是WCF希望将所有异常转换为客户端故障,以保持服务运行; I actually want to take the entire process down, which essentially means circumventing WCF's normal behavior. 我实际上想要完成整个过程,这实际上意味着绕过WCF的正常行为。

Environment.FailFast() will create a crash dump; Environment.FailFast()将创建一个崩溃转储; it will not run any pending try-finally blocks nor will it run any finalizers. 它不会运行任何挂起的try-finally块,也不会运行任何终结器。

You need to use IErrorHandler to customize WCF's error handling behavior. 您需要使用IErrorHandler来自定义WCF的错误处理行为。 You "apply the behavior" before you call (ServiceHost).Open(). 您在调用(ServiceHost).Open()之前“应用行为”。

For example (look for the line that says "serviceHost.Description.Behaviors.Add(new FailBehavior());" in Main()): 例如(在Main()中查找“serviceHost.Description.Behaviors.Add(new FailBehavior());”中的行:

class FailBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        Console.WriteLine("The FailFast behavior has been applied.");
        var f = new FailOnError();
        foreach(ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers)
        {
            chanDisp.ErrorHandlers.Add(f);      
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        return;
    }
}

class FailOnError : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        // this is called for every exception -- even ungraceful disconnects
        if( !(error is CommunicationException) )
            throw new TargetInvocationException( "WCF operation failed.", error );
        else
            throw new CommunicationException( "Unexpected communication problem. (see inner exception)", error );

        // Unreachable
        //return false; // other handlers should be called
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        // Can't throw from here (it will be swallowed), and using Environment.FailFast
        // will result in all crashes going to the same WER bucket. We could create
        // another thread and throw on that, but instead I think throwing from HandleError
        // should work.

        //Console.WriteLine( "Unhandled exception: {0}", error );
        //Environment.FailFast("Unhandled exception thrown -- killing server");            
    }
}

class Program
{
    static void Main( string[] args )
    {
        Console.WriteLine( "Greetings from the server." );

        Uri uri = new Uri( "net.tcp://localhost:5678/ServerThatShouldCrash" );
        using( ServiceHost serviceHost = new ServiceHost( typeof( Server ), uri ) )
        {
            Binding binding = _CreateBinding();

            serviceHost.AddServiceEndpoint( typeof( IServer ),
                                            binding,
                                            uri );
            serviceHost.Description.Behaviors.Add(new FailBehavior());
            serviceHost.Open();

            // The service can now be accessed.
            Console.WriteLine( "The service is ready." );
            Console.WriteLine( "\nPress <ENTER> to terminate service.\n" );
            Console.ReadLine();
        }
    }

    private static Binding _CreateBinding()
    {
        NetTcpBinding netTcp = new NetTcpBinding( SecurityMode.None );
        netTcp.ReceiveTimeout = TimeSpan.MaxValue;
        netTcp.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
        return netTcp;
    } // end _CreateBinding()
}
Application.Exit();

这可能会做到,但用户将失去他们当时正在做的任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何捕获另一个进程的未处理异常? - How can I catch the unhandled exceptions of another process? 如果后台线程中有未处理的异常,如何使主进程崩溃 - how to crash the main process if there is unhandled exception inside background thread 如何让WinForms静静地忽略未处理的异常? - How can I get WinForms to stop silently ignoring unhandled exceptions? 如何以DRY方式将未处理的程序异常通知管理员? - How can I notify administrators of unhandled program exceptions in a DRY way? 如何允许Task异常传播回UI线程? - How can I allow Task exceptions to propagate back to the UI thread? 如何在 dot net core 中设置 log4net 以记录所有未处理的异常? - How can I set up log4net in dot net core to log all unhandled exceptions? 如何阻止 IConnectableObservable.Wait() 吞下未处理的异常? - How can I stop IConnectableObservable.Wait() from swallowing unhandled exceptions? 如何在 WinForms 应用程序中创建一些可以捕获所有“未处理”异常的东西? - How can I make something that catches all 'unhandled' exceptions in a WinForms application? 线程在wcf服务中中止了异常 - Thread aborted exceptions in wcf service 未处理的异常会使WCF服务崩溃吗? - unhandled exception will make WCF service crash?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM