简体   繁体   English

未处理的异常会使WCF服务崩溃吗?

[英]unhandled exception will make WCF service crash?

I want to know whether unhandled exception will make WCF service crash. 我想知道未处理的异常是否会使WCF服务崩溃。 I have written the following program which shows unhandled exception in a thread started by WCF service will make the whole WCF service crash. 我编写了以下程序,该程序显示WCF服务启动的线程中未处理的异常将使整个WCF服务崩溃。

My question is, I want to confirm whether unhandled exception in threads (started by WCF service) will make WCF crash? 我的问题是,我想确认线程中未处理的异常(由WCF服务启动)是否会使WCF崩溃? My confusion is I think WCF should be stable service which should not crash because of unhandled exception. 我的困惑是,我认为WCF应该是稳定的服务,不应因未处理的异常而崩溃。

I am using VSTS 2008 + C# + .Net 3.5 to develop a self-hosted Windows Service based WCF service. 我正在使用VSTS 2008 + C#+ .Net 3.5开发基于WCF服务的自托管Windows服务。

Here are the related parts of code, 这是代码的相关部分,

namespace Foo
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        string Submit(string request);
    }
}

namespace Foo
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class FooImpl : IFoo
    {
        public string Submit(string request)
        {
            return String.Empty;
        }
    }
}

namespace Foo
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        ServiceHost host = new ServiceHost(typeof(FooImpl));

        protected override void OnStart(string[] args)
        {
            host.Open();
            // start a thread which will throw unhandled exception
            Thread t = new Thread(Workerjob);
            t.Start();
        }

        protected override void OnStop()
        {
            host.Close();
        }

        public static void Workerjob()
        {
            Thread.Sleep(5000);
            throw new Exception("unhandled");
        }
    }
}

An unhandled exception on the service side will cause the channel (the connection between the client and the server) to "fault" - eg to be torn down. 服务端未处理的异常将导致通道(客户端和服务器之间的连接)“发生故障”,例如被拆除。

From that point on, you cannot call from the client using the same proxy client object instance anymore - you'll have to re-create the proxy client. 从那时起,您将无法再使用相同的代理客户端对象实例从客户端进行调用-您将不得不重新创建代理客户端。

Your best bet is to handle all error on the server side whenever possible. 最好的选择是尽可能处理服务器端的所有错误。 Check out the IErrorHandler interface, which you should implement on your service implementation class, to turn all unhandled .NET exceptions into either SOAP faults (which will NOT cause the channel to fault), or to report / swallow them entirely. 检出应该在服务实现类上实现的IErrorHandler接口,以将所有未处理的.NET异常转换为SOAP错误( 不会导致通道故障),或者完全报告/吞噬它们。

Marc

Yes, an unhandled exception in a thread will take the process down. 是的,线程中未处理的异常会导致进程中断。

This process will crash: 此过程将崩溃:

static void Main(string[] args)
{
    Thread t = new Thread(() =>
    {
        throw new NullReferenceException();
    });
    t.Start();
    Console.ReadKey();
}

This one will not: 这将不会:

static void Main(string[] args)
{
    Thread t = new Thread(() =>
    {
        try
        {
            throw new NullReferenceException();
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception.ToString());
        }
    });
    t.Start();
    Console.ReadKey();
}

The default behavior of the WCF runtime is to swallow all but a few types exceptions. WCF运行时的默认行为是吞入除少数几种类型之外的所有异常。 So if your code throws an exception down the stack to the WCF runtime (such as if you throw from a WCF operation), it will NOT crash the app (unless it is deemed a "fatal" exception, such as OOM, SEHException, etc.). 因此,如果您的代码向WCF运行时抛出了异常(例如,从WCF操作中抛出),则它不会使应用程序崩溃(除非它被视为“致命”异常,例如OOM,SEHException等) )。 If the exception is not part of the operation's fault contract, then the channel will be faulted, otherwise not. 如果异常不是操作故障合同的一部分,则通道将发生故障,否则就不会发生故障。

If the WCF runtime is not under your code on the stack, then the exception /will/ crash the process. 如果WCF运行时不在堆栈上的代码下,则异常/ will /将使进程崩溃。

This is similar to the ASP.NET runtime. 这类似于ASP.NET运行时。

If you would like to screen for exceptions flying out of WCF operations in a general way, I recommend using the IOperationInvoker interface. 如果您希望以一般方式筛选出WCF操作中溢出的异常,建议使用IOperationInvoker界面。 You can also use IErrorHandler, but your IErrorHandler implementation will be notified of exceptions other than those thrown from "user code" (WCF operations), such as SocketAbortedExceptions on WCF internal I/O threads, which are probably not interesting to you. 您也可以使用IErrorHandler,但是将向IErrorHandler实现通知除“用户代码”(WCF操作)引发的异常以外的其他异常,例如WCF内部I / O线程上的SocketAbortedException,这些异常可能对您而言并不有趣。

If you don't handle an exception it gets passed on the operating system and it will respond by killing what ever application caused the exception. 如果您不处理异常,它将在操作系统上传递,并且它将通过杀死导致该异常的应用程序做出响应。

Why don't you just add a try/catch to handle the exceptions so that your service is not killed ? 您为什么不只添加try / catch来处理异常,以使服务不会被杀死?

If you don't have proper error handling it will make the program crash. 如果没有适当的错误处理,它将使程序崩溃。 Its good practise to put a 好的做法是

try{//do something
}
catch{ //handle errors
}
finally{//final clean up
}

block in your code to make sure that if it does throw an exception is to handle it gracefully. 在您的代码中进行阻止,以确保是否确实引发了异常。 examples at http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx http://msdn.microsoft.com/zh-cn/library/fk6t46tz(VS.71).aspx上的示例

You can make use of FaultException to communicate errors to the client side and keep the logic in the service. 您可以使用FaultException将错误传达给客户端,并将逻辑保留在服务中。

Check this example , hope it helps you. 检查此示例 ,希望对您有所帮助。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM