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

时间:2009-07-16 07:53:07

标签: c# .net wcf visual-studio-2008 windows-services

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

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

我正在使用VSTS 2008 + C#+ .Net 3.5开发基于Windows服务的自托管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");
        }
    }
}

6 个答案:

答案 0 :(得分:18)

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

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

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

马克

答案 1 :(得分:11)

是的,线程中的未处理异常将使该过程失效。

此过程将崩溃:

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();
}

答案 2 :(得分:7)

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

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

这与ASP.NET运行时类似。

如果您希望以一般方式筛选出WCF操作之外的异常,我建议使用IOperationInvoker界面。您也可以使用IErrorHandler,但是您的IErrorHandler实现将被通知除“用户代码”(WCF操作)之外的异常,例如WCF内部I / O线程上的SocketAbortedExceptions,这可能对您不感兴趣。

答案 3 :(得分:3)

如果你没有处理异常,它会在操作系统上传递,它将通过杀死应用程序导致异常的内容来做出响应。

为什么不直接添加 try / catch 来处理异常,以免您的服务被杀?

答案 4 :(得分:1)

如果您没有正确的错误处理,它将导致程序崩溃。

的好习惯
try{//do something
}
catch{ //handle errors
}
finally{//final clean up
}

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

的示例

答案 5 :(得分:1)

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

检查example,希望对您有帮助。