2009-08-06 8 views
14

Ich habe eine Client-Anwendung, die alle 10 Sekunden versucht, eine Nachricht über ein WCF-Webdienst zu senden. Diese Client-App wird auf einem Computer an Bord eines Schiffes installiert sein, von dem wir wissen, dass es eine sporadische Internetverbindung haben wird. Ich möchte, dass die App versucht, Daten über den Dienst zu senden, und wenn dies nicht möglich ist, die Nachrichten so lange in Warteschlange zu stellen, bis sie sie über den Dienst senden können.von einem CommunicationObjectFaultedException in WCF Wiederherstellen

Um diese Einstellung zu testen, beginne ich mit der Client-Anwendung und den Web-Service (sowohl auf meinem lokalen Rechner), und alles funktioniert. Ich versuche, die schlechte Internet-Verbindung zu simulieren, indem ich den Web-Service abtöte und neu starte. Sobald ich den Dienst beendet habe, beginne ich CommunicationObjectFaultedExceptions - was erwartet wird. Aber nachdem ich den Dienst neu gestartet habe, erhalte ich weiterhin diese Ausnahmen.

Ich bin mir ziemlich sicher, dass ich etwas über das Web-Service-Paradigma nicht verstehe, aber ich weiß nicht, was das ist. Kann jemand Ratschläge geben, ob diese Einrichtung möglich ist oder nicht, und wenn ja, wie dieses Problem zu lösen ist (d. H. Den Kommunikationskanal mit dem Web-Service wiederherstellen)?

Dank!

Klay

Antwort

33

-Client-Dienst-Proxies können nicht wiederverwendet werden, wenn sie bemängelt haben. Sie müssen die alte entsorgen und eine neue erstellen.

Sie müssen auch sicherstellen, dass Sie den Client-Service-Proxy ordnungsgemäß schließen. Es ist möglich, dass ein WCF-Dienstproxy beim Schließen eine Ausnahme auslöst, und wenn dies geschieht, wird die Verbindung nicht geschlossen. Daher müssen Sie den Vorgang abbrechen. Verwenden Sie das Muster "try {Close}/catch {Abort}". Auch bedenken, dass die dispose-Methode nahe nennt (und damit eine Ausnahme von der dispose werfen kann), so dass Sie nicht nur eine Verwendung wie mit normalen Einweg-Klassen verwenden können.

Zum Beispiel:

try 
{ 
    if (yourServiceProxy != null) 
    { 
     if (yourServiceProxy.State != CommunicationState.Faulted) 
     { 
      yourServiceProxy.Close(); 
     } 
     else 
     { 
      yourServiceProxy.Abort(); 
     } 
    } 
} 
catch (CommunicationException) 
{ 
    // Communication exceptions are normal when 
    // closing the connection. 
    yourServiceProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    // Timeout exceptions are normal when closing 
    // the connection. 
    yourServiceProxy.Abort(); 
} 
catch (Exception) 
{ 
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards. 
    yourServiceProxy.Abort(); 
    throw; 
} 
finally 
{ 
    // This is just to stop you from trying to 
    // close it again (with the null check at the start). 
    // This may not be necessary depending on 
    // your architecture. 
    yourServiceProxy = null; 
} 

Es gibt einen Blog-Artikel über diesen here

+0

10, wenn ich könnte - wow, dieses Verhalten völlig unter dem Radar ist, nie, was hätte geklappt vorging wenn ich nicht auf diese Antwort gestoßen wäre. –

+0

Bravo! Ich habe eine Version davon als eine Erweiterungsmethode implementiert: TryDispose für die Proxy-Klasse für die Verwendung durch andere. –

+0

@ Moby's Stunt Double - kannst du deinen Code teilen? – RichardHowells