ich das noch nicht gesehen haben, antwortete ziemlich einfache Einrichtung ...WCF einen Dienst von einem Dienst aufrufen
Frage: Ich bin ein Deadlock bekommen, möchte ich wissen, wie es zu vermeiden, da mein Setup .
Ich habe ServiceA, die IServiceA und ServiceB implementiert, die IServiceB implementiert. Beide Dienste werden als "PerSession" und "einspringenden" gekennzeichnet ...
IServiceA unterstützt diese Methode:
DataA GetDataA();
IServiceB unterstützt diese Methode:
DataB GetDataB();
in meiner app, ich Aufruf ServiceA GetDataA()
Methode, und in ServiceA's GetDataA-Methode, es öffnet eine Proxy-Verbindung zu ServiceB und ruft GetDataB()
.
GetDataB am Service-Ende (nicht am Ende des Clients) wird korrekt ausgeführt (das Debug-Protokoll sagt dies), aber wenn es versucht, die Daten an ServiceA zurückzugeben, wird es deadlocks.
Ich nehme an, das ist, weil, wenn ich in ServiceA von "Benutzer" rief, er die IO-Abschluss-Port "Lieferung Sperre" (oder vielleicht ist es WCF pro Sitzung "Sperre. Auf jeden Fall eine Sperre Ich nehme an, dass, wenn ServiceB's GetDataB()
versucht, den Wert zurückzugeben, was ist es wirklich getan ist um den Kanal herum und versucht, eine Empfangsmethode auf ServiceA, die die Sperre und Deadlocks benötigt, die die Sperre und Deadlocks benötigt Jede Frage, die ich bisher gelesen habe, wo die Leute fragen "ist es in Ordnung, einen Dienst von einem anderen zu ketten", war jede (dumme) Antwort "sicher! mach weiter! nichts dran! Dienste wissen nicht, ob sie es sind durch normalen .NET-Code aufgerufen werden oder wenn sie von einem anderen Dienst angerufen werden! ". Ärgerlich. Es gibt sicherlich" einige Ding dazu ", auch wenn es ein kleines bisschen trivial ist.
Ich habe gelesen, dass ich Methoden nicht markieren kann, die Werte als "Einweg" zurückgeben. Und sie als "Wiedereinsteiger" zu markieren ... sollte das funktionieren oder nicht? Ich weiß, wenn ich in meinem Dienst einen Rückruf rufe, wird die Sperre stillgelegt. Was ist, wenn ich einen anderen Dienst anrufe? ist WCF intelligent genug, um auch in diesem Fall das Schloss freizugeben?
Ich könnte meine Dienste als "multiple" anstelle von "re-entrant" markieren, aber ich frage mich (a) ist der Deadlock wirklich von dem, was ich denke, oder könnte es von etwas anderem sein, und (b) Gibt es einen besseren Weg dazu?
Die "dummen" Antworten, die Sie gesehen haben, sind so, weil das Verketten von Serviceaufrufen (normalerweise) einfach nur "dumm" einfach ist. Es muss etwas anderes zu deinem speziellen Fall geben. Haben Sie [WCF trace] (http://stackoverflow.com/a/4271597/21567) aktiviert/angeschaut? Vielleicht möchten Sie mehr (technische) Informationen zu Ihrem Setup bereitstellen (Code, Konfiguration usw.). –
Natürlich können Sie Service-Anrufe von anderen Diensten ketten, ich habe es viele, viele Male getan. Vielleicht, wenn Sie Ihren Code auf Github hosten könnten (oder ihn zumindest mit einer Demo-App neu erstellen, die das Problem nachbildet) oder etwas, könnte es den Leuten einen besseren Kontext geben, mit was Sie arbeiten, um Ihnen zu helfen. Es scheint, dass Sie ein spezielles Schneeflockenszenario erreicht haben oder etwas falsch konfiguriert wurde, wer weiß. –
also ... der Deadlock "sollte nicht passieren"? Wenn der Stack-Pointer momentan in der GetDataA() -Methode von ServiceA ist und ich die GetDataB() -Methode von ServiceB aufruft und GetDataB() ausführt und versucht, mich mit den resultierenden Daten zurückzurufen, sollte es nicht durch das Versuch Deadlocking sein die Empfangssperre in ServiceA? Ich habe eine Test-App geschrieben, um dies zu demonstrieren, eine mit zwei Diensten, und ich bin überrascht, dass ich es NICHT festgefahren sehe, aber ich kann nicht herausfinden, warum es nicht festgefahren ist. Sollte es nicht sein? Wenn B versucht, die Daten an A zurückzugeben, sollte es nicht versuchen, eine Sperre zu erhalten und fehlschlagen? –