未处理的异常会使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");
}
}
}
是,在一个线程中未处理的异常将下跌过程。
这个过程将会崩溃:
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();
}
谢谢,很高兴知道。 – George2 2009-07-16 08:12:57
如果你不处理它就会在操作系统上传递了一个例外,它会杀死回应什么曾经的应用程序导致了这种异常
为什么不只是添加一个try/catch来处理异常,以便您的服务不会被杀死?
如果异常发生在主线程以外的线程中,则不应该。参见上面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以外的异常,这些异常可能对您不感兴趣。
您的示例不会显示“由WCF服务启动的线程中未处理的异常”,而是“由Windows服务启动的线程中的未处理的异常”。它与WCF无关。 – 2009-07-16 08:03:32
我在Windows Service(host.Open())中启动WCF自身主机,我的意思是WCF服务中的未处理异常。抱歉,这个令人困惑的词汇,以及对我的问题的任何评论或回答? – George2 2009-07-16 08:05:09