views:

1547

answers:

5

Hello everyone,

I want to know whether unhandled exception will make WCF service crash. I have written the following program which shows unhandled exception in a thread started by WCF service will make the whole WCF service crash.

My question is, I want to confirm whether unhandled exception in threads (started by WCF service) will make WCF crash? My confusion is I think WCF should be stable service which should not crash because of unhandled exception.

I am using VSTS 2008 + C# + .Net 3.5 to develop a self-hosted Windows Service based WCF service.

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

thanks in advance, George

+3  A: 

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();
}
Fredrik Mörk
Thanks, good to know that.
George2
+1  A: 

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 ?

jussij
Not if the exception occurs in a thread other than the main thread. See Fredrik Mörk's example above.
Luke Venediger
In Fredrik's example there is a try/catch block to stop the exception from bringing down the process, which is exactly what I said above.
jussij
+1  A: 

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

AutomatedTester
+3  A: 

An unhandled exception on the service side will cause the channel (the connection between the client and the server) to "fault" - e.g. 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.

Marc

marc_s
Hi Marc, I read your recommended MSDN link about IErrorHandler carefully. One confusion, the unhandled exception of my problem is from a thread which is started by myself explciitly, and it is not a WCF operation thread. I think IErrorHandler catches unhandled exception in WCF operation thread (i.e. the thread which performs OperationContract operations), and since my thread is not WCF operation thread, it is not related to my problem, correct? Any comments?
George2
did you start that thread from your WCF server code? The question really is: will crashing your thread affect your server code - if it leads to an exception in your server code, then implementing the IErrorHandler interface will help.
marc_s
Thanks Marc, 1. I am confused about what means "start that thread from your WCF server code", could you clarify please? WCF from developer point of view is just a set of Contracts, I am not sure what do you mean WCF server. :-) 2. You mean unhandled exception from non-WCF thread will also be caught by IErrorHandler?
George2
Yes, you have contracts - but you also have to have a class on the server side which actually IMPLEMENTS that service contract. That's what I'm talking about. Is your thread being created and run from the server side implementation of your service contract?
marc_s
+1  A: 

The default behavior of the WCF runtime is to swallow all but a few types exceptions. 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.). 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.

This is similar to the ASP.NET runtime.

If you would like to screen for exceptions flying out of WCF operations in a general way, I recommend using the IOperationInvoker interface. 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.

Dan T