7 Stimmen

eine unbehandelte Ausnahme den WCF-Dienst zum Absturz bringt?

Ich möchte wissen, ob eine unbehandelte Ausnahme den WCF-Dienst zum Absturz bringt. Ich habe das folgende Programm geschrieben, das zeigt, dass eine unbehandelte Ausnahme in einem Thread, der vom WCF-Dienst gestartet wurde, den gesamten WCF-Dienst zum Absturz bringt.

Meine Frage ist, ich möchte bestätigen, ob unbehandelte Ausnahme in Threads (gestartet von WCF-Dienst) WCF zum Absturz bringen wird? Meine Verwirrung ist ich denke WCF sollte stabilen Dienst, der nicht wegen unbehandelten Ausnahme abstürzen sollte.

Ich verwende VSTS 2008 + C# + .Net 3.5, um einen selbst gehosteten Windows Service-basierten WCF-Dienst zu entwickeln.

Hier sind die entsprechenden Teile des Codes,

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 Stimmen

Ihr Beispiel zeigt nicht "unbehandelte Ausnahme in einem vom WCF-Dienst gestarteten Thread", sondern "unbehandelte Ausnahme in einem vom Windows-Dienst gestarteten Thread". Das hat nichts mit WCF zu tun.

0 Stimmen

Ich starte WCF selbst Host in Windows Service (host.Open()), die ich unbehandelte Ausnahme in WCF-Dienst bedeuten. Sorry für den verwirrenden Begriff, und alle Kommentare oder Antworten auf meine Frage?

18voto

marc_s Punkte 701497

Eine unbehandelte Ausnahme auf der Seite des Dienstes führt dazu, dass der Kanal (die Verbindung zwischen dem Client und dem Server) "fehlerhaft" ist, d. h. abgebaut wird.

Von diesem Zeitpunkt an können Sie nicht mehr vom Client aus mit der gleichen Proxy-Client-Objektinstanz aufrufen - Sie müssen den Proxy-Client neu erstellen.

Am besten ist es, wenn Sie alle Fehler auf der Serverseite behandeln, wann immer dies möglich ist. Schauen Sie sich die IErrorHandler Schnittstelle, die Sie in Ihrer Dienstimplementierungsklasse implementieren sollten, um alle unbehandelten .NET-Ausnahmen entweder in SOAP-Fehler zu verwandeln (die dann NICHT zu einer Störung des Senders führen), oder sie ganz zu melden/zu schlucken.

Marc

0 Stimmen

Hallo Marc, ich habe Ihren empfohlenen MSDN-Link über IErrorHandler sorgfältig gelesen. Eine Verwirrung, die unbehandelte Ausnahme meines Problems ist von einem Thread, der explizit von mir selbst gestartet wird, und es ist nicht ein WCF-Operationsthread. Ich denke, IErrorHandler fängt unbehandelte Ausnahmen im WCF-Operationsthread ab (d. h. der Thread, der OperationContract-Operationen ausführt), und da mein Thread kein WCF-Operationsthread ist, steht er nicht in Zusammenhang mit meinem Problem, richtig? Irgendwelche Kommentare?

1 Stimmen

Haben Sie diesen Thread von Ihrem WCF-Servercode aus gestartet? Die eigentliche Frage ist: Wird sich der Absturz Ihres Threads auf Ihren Servercode auswirken - wenn er zu einer Ausnahme in Ihrem Servercode führt, dann hilft die Implementierung der IErrorHandler-Schnittstelle.

0 Stimmen

Danke Marc, 1. ich bin verwirrt über was bedeutet "starten Sie diesen Thread von Ihrem WCF-Server-Code", könnten Sie bitte klären? WCF ist aus Entwicklersicht nur ein Satz von Verträgen, ich bin mir nicht sicher, was Sie mit WCF-Server meinen :-) 2. Sie meinen, unbehandelte Ausnahmen von Nicht-WCF-Threads werden auch von IErrorHandler abgefangen?

11voto

Fredrik Mörk Punkte 151006

Ja, eine unbehandelte Ausnahme in einem Thread führt zum Abbruch des Prozesses.

Dieser Prozess wird abstürzen:

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

Dies wird nicht der Fall sein:

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

8voto

Das Standardverhalten der WCF-Laufzeit ist, alle Ausnahmen bis auf einige wenige Typen zu schlucken. Wenn Ihr Code also eine Ausnahme den Stack hinunter zur WCF-Laufzeit wirft (z. B. wenn Sie eine Ausnahme von einer WCF-Operation aus werfen), wird die Anwendung NICHT abstürzen (es sei denn, es handelt sich um eine "fatale" Ausnahme, wie OOM, SEHException usw.). Wenn die Ausnahme nicht Teil des Fehlervertrags der Operation ist, dann wird der Kanal fehlerhaft, ansonsten nicht.

Wenn die WCF-Laufzeit nicht unter Ihrem Code auf dem Stapel liegt, wird die Ausnahme den Prozess zum Absturz bringen.

Dies ist ähnlich wie bei der ASP.NET-Laufzeitumgebung.

Wenn Sie Ausnahmen, die bei WCF-Operationen auftreten, allgemein überwachen möchten, empfehle ich die Verwendung der Schnittstelle IOperationInvoker. Sie können auch IErrorHandler verwenden, aber Ihre IErrorHandler-Implementierung wird über Ausnahmen benachrichtigt, die nicht von "Benutzercode" (WCF-Operationen) ausgelöst werden, wie z. B. SocketAbortedExceptions auf WCF-internen E/A-Threads, die für Sie wahrscheinlich nicht interessant sind.

3voto

jussij Punkte 10221

Wenn Sie eine Ausnahme nicht behandeln, wird sie an das Betriebssystem weitergeleitet, das daraufhin die Anwendung, die die Ausnahme verursacht hat, beendet.

Warum fügst du nicht einfach ein try/catch um die Ausnahmen zu behandeln, damit Ihr Dienst nicht beendet wird?

0 Stimmen

Nicht, wenn die Ausnahme in einem anderen Thread als dem Hauptthread auftritt. Siehe das obige Beispiel von Fredrik Mörk.

0 Stimmen

In Fredriks Beispiel gibt es einen try/catch-Block, um zu verhindern, dass die Ausnahme den Prozess zum Stillstand bringt, was genau dem entspricht, was ich oben gesagt habe.

1voto

AutomatedTester Punkte 21864

Wenn Sie keine angemessene Fehlerbehandlung haben, wird das Programm abstürzen. Es ist gute Praxis, eine

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

Block in Ihren Code einbauen, um sicherzustellen, dass er im Falle einer Ausnahme ordnungsgemäß damit umgeht. Beispiele unter http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X