[英]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.