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

问题描述:

我想知道未处理的异常是否会导致WCF服务崩溃。我写了下面的程序,它显示了由WCF服务启动的线程中的未处理的异常将导致整个WCF服务崩溃。未处理的异常会使WCF服务崩溃?

我的问题是,我想确认线程中的未处理异常(由WCF服务启动)是否会导致WCF崩溃?我的困惑是我认为WCF应该是稳定的服务,不应该因为未处理的异常而崩溃。

我使用VSTS 2008 + C#+ .Net 3.5开发自托管的基于Windows Service的WCF服务。

这里是代码的相关部分,

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"); 
     } 
    } 
} 
+2

您的示例不会显示“由WCF服务启动的线程中未处理的异常”,而是“由Windows服务启动的线程中的未处理的异常”。它与WCF无关。 – 2009-07-16 08:03:32

+0

我在Windows Service(host.Open())中启动WCF自身主机,我的意思是WCF服务中的未处理异常。抱歉,这个令人困惑的词汇,以及对我的问题的任何评论或回答? – George2 2009-07-16 08:05:09

是,在一个线程中未处理的异常将下跌过程。

这个过程将会崩溃:

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

这一个不会:

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

谢谢,很高兴知道。 – George2 2009-07-16 08:12:57

如果你不处理它就会在操作系统上传递了一个例外,它会杀死回应什么曾经的应用程序导致了这种异常

为什么不只是添加一个try/catch来处理异常,以便您的服务不会被杀死?

+0

如果异常发生在主线程以外的线程中,则不应该。参见上面FredrikMörk的例子。 – user141682 2010-01-21 15:15:09

如果你没有正确的错误处理,它会使程序崩溃。它很好的做法,把

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

块在你的代码,以确保如果它抛出一个异常,是优雅地处理它。 http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx

服务端未处理的异常将导致通道(客户端与服务器之间的连接)“故障” - 例如,被拆除。

从那时起,您无法再使用相同的代理客户端对象实例从客户端调用 - 您必须重新创建代理客户端。

最好的办法是尽可能处理服务器端的所有错误。查看您应该在服务实现类上实现的IErrorHandler接口,将所有未处理的.NET异常转换为SOAP错误(其中不是会导致通道出错)或者完全报告/吞下它们。

马克

WCF运行时的默认行为是吞下所有,但一些类型的异常。因此,如果您的代码将堆栈中的异常向WCF运行时抛出(例如,如果您从WCF操作中抛出),它不会使应用程序崩溃(除非它被视为“致命”异常,例如OOM,SEHException等)。如果异常不是操作故障合同的一部分,则通道将发生故障,否则不会发生。

如果WCF运行时不在栈上的代码之下,那么异常/将会/使进程崩溃。

这与ASP.NET运行时类似。

如果您想通过一般方式筛选掉WCF操作中的异常,我建议使用IOperationInvoker接口。您也可以使用IErrorHandler,但您的IErrorHandler实现将被通知除了那些从“用户代码”(WCF操作)抛出的异常,例如WCF内部I/O线程上的SocketAbortedExceptions以外的异常,这些异常可能对您不感兴趣。

您可以使用FaultException将错误传达给客户端并将逻辑保留在服务中。

检查此example,希望它可以帮助你。