2009-08-17 20 views
1

Ich laufe einen WCF-Dienst, und Servicehost Open() Methode aufrufen wird eine AddressAlreadyInUseException erhöhen, wenn die Adresse ..err ist .. bereits im Einsatz!Wie kann ich verhindern, dass die AddressAlreadyInUseException ausgelöst wird?

Gibt es eine Möglichkeit zu testen, ob die Adresse verfügbar ist, ohne eine Ausnahme auszulösen?

+0

möglicherweise Sie suchen, wie http://stackoverflow.com/questions/283145/how-to-prevent-visual-studio-launch-wcfsvchost-exe-in-debuggin – Abdu

Antwort

3

Die vom ServiceHost verwendeten Adressen sind in ServiceHost.BaseAddresses aufgeführt. Sie könnten dies möglicherweise vor Ihrem Anruf überprüfen.

Alternativ versuchen Sie einfach, den Dienst zu öffnen und die AddressAlreadyInUseException ordnungsgemäß abzufangen und zu behandeln. Wenn Sie das erhalten, wissen Sie, dass es verwendet wird, und Sie können zu Ihrer sekundären Logik weitergehen.

+0

in meinem Szenario, eine weitere Instanz von Der Server verwendet die Adresse. Wenn ich es richtig verstehe, enthält ServiceHost.BaseAddresses nur die Adressen, die vom aktuellen Prozess verwendet werden, wenn ich Open auf dem ServiceHost aufruft. Ihre alternative Lösung ist, was ich gerade mache, aber ich würde lieber vermeiden unnötige Ausnahmen zu vermeiden, wenn ich kann ... – Brann

+0

Wenn es ein separater Server ist, der die Adresse verwendet, dann ist die Behandlung der Ausnahme die beste Option. –

+0

Die Behandlung der Rezeption zwingt mich, ein neues ServiceHost-Objekt neu zu erstellen, da sich das aktuelle Objekt im Status Faulted befindet und nicht mehr verwendet werden kann. – Brann

3

Sie könnten ein wenig bekanntes Feature der WCF-Endpunktkonfigurationen versuchen: ListenUriMode.Unique. Skonnard hat eine wirklich gute write-up dazu: http://www.pluralsight.com/community/blogs/aaron/archive/2006/04/24/22610.aspx

Ich weiß nicht, ob dies Ihre aktuelle Szenario behandelt (ich weiß nicht, ob es die Kollision erkennt und ob Sie mit ihm in Ordnung sind spooling auf einer anderen Adresse), aber es könnte nur.

Dies ist möglicherweise auch keine praktikable Lösung, wenn Sie keine zentrale Möglichkeit haben, Endpunktadressen an Ihre Clients (Datenbank usw.) zu übermitteln. WS-Discovery eine Möglichkeit hat, um diese Einschränkung bekommen, aber Sie würden bis .NET 4.0 warten, oder einen der Open-Source-Implementierungen für WCF 3.5 verwenden.

1

Sie können nicht.

Betrachten Sie den Code:

 if(AddressIsFree(addr)) 
     { 
      OpenServiceOn(addr); 
     } 

Was sonst, wenn etwas passiert den Hafen in diesem Bruchteil einer Sekunde zwischen dem Check registriert, und wenn Sie den Service öffnen? Es ist eine Wettlaufbedingung.

Der richtige Weg, um dies zu umgehen, ist einfach versuchen, den Port zu öffnen, und die Ausnahme abfangen, wenn es fehlschlägt, und etwas tun, um zu kompensieren. Ausnahmen sind nicht schlecht. Sie existieren zum Teil genau aus diesem Grund. Es gibt keinen Grund, zu versuchen und zu tun viel sicherer als eine Ausnahme zu machen Überprüfung nicht geworfen werden - in den meisten Fällen nur versuchen, den Betrieb und die Ausnahme abfangen, wenn sie auftritt.

Sie sind in der Regel nicht einmal viel mehr Code.

+1

Race-Bedingungen können durch die richtige Verwendung eines Synchronisationsmechanismus behoben werden. Es gibt viele Gründe, Ausnahmen zu vermeiden (siehe http://stackoverflow.com/questions/729379/why-not-use-exceptions-asregular-flow-of-control zum Beispiel). Oder befürworten Sie die Verwendung von double.parse anstelle von double.tryparse? – Brann

+4

Dies ist eine Wettlaufsituation mit der Umgebung, ähnlich wie das Erstellen einer Datei nur, wenn sie nicht existiert. Genauso wie wir die Datei mit exclusive create geöffnet haben, ist der einzige sichere Weg, dies zu versuchen, die Ausnahme zu fangen, wenn sie fehlschlägt. Sie können die Umgebung nicht sperren. Der Hauptgrund, um Ausnahmen zu vermeiden, ist die Leistung, zum Beispiel, wenn Sie potenziell 100 Ausnahmen pro Sekunde auslösen. Da in diesem Szenario das unwahrscheinlich ist, steht meine Empfehlung :) – kyoryu

0

Falls das hilft niemandem. Ich hatte das gleiche Problem beim Versuch, einen WCF-Dienst in der Konsolenanwendung zu hosten. Was ich getan habe, war das Öffnen der Eigenschaft der wcf-Servicebibliothek (Alt + Enter oder Rechtsklick-> Eigenschaft), dann auf die Registerkarte WCF-Optionen im Eigenschaftsfenster gehen und die Option "WCF-Servicehost starten beim Debuggen eines anderen Projekts in derselben Lösung" deaktivieren. THen das Problem ist behoben.

Verwandte Themen