Ich habe eine WCF-Client/Server-App, die über HTTP mit der WSHttpBinding kommuniziert.WCF Concurrent-Anfragen häufen sich auf dem Server bei Verwendung von WSHttpBinding
Serverkonfiguration: Self-Hosting, mit dem Standard WCF ServiceHost
. Meine eigentliche Dienstklasse zugeschrieben als:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerSession,
UseSynchronizationContext = false)]
Client Setup: (. proxy.call_server_method
Blöcke so lange, bis der Server vollständig reagiert hat) mit einem visuell-Studio erzeugt Client-Proxy mit synchronen Service Calls
Szenario: Ich habe einen bestimmten Methodenaufruf, der 20 Sekunden dauert, um auf dem Server auszuführen. Der Client ruft diese Methode in einem separaten Thread auf, so dass er nicht aufgehalten wird, und die ConcurrencyMode.Multiple
bedeutet, dass WCF sie in einem separaten Thread auf dem Server ausführen sollte.
Diese Theorie wird durch die Tatsache unterstützt, dass alles funktioniert gut, wenn ich meine App für die Verwendung NetTcpBinding
konfigurieren.
Problem:
Wenn ich die App konfigurieren WSHttpBinding
zu verwenden, dann ist diese lange Methodenaufruf bewirkt, dass die HTTP-Anfragen zu 'back up'. Ich habe dieses Verhalten sowohl durch die Überprüfung meiner Protokolle als auch durch das Debuggen der HTTP-Anfragen mit Fiddler überprüft.
Beispiel:
- Client leitet 20-Sekunden langen Anfrage auf einem Hintergrund-Thread
- Client-Anforderung B und C auf den Vordergrund Gewinde
- Requests B und C an den Server geschickt bekommen einleitet, die doesn ‚t verarbeiten sie, bis sie mit der 20-Sekunden langen Anfrage
Aber manchmal getan wird:
- Anfragen B und C werden nicht gesendet (sie erscheinen nicht einmal in Fiddler), bis die 20-Sekunden-Anfrage zurückkommt (das ist selten).
- Hinweis: Die Einstellung
<add address="*" maxconnection="100"/>
in der app.config des Clients hat dies (scheinbar) zum Stoppen gebracht.
Hier ist eine Zeitleiste von Fiedler das Problem demonstriert: (klicken für größere Version)
Wie Sie sehen können, werden die Anfragen alle auf dem Server gesichert zu werden. Sobald die 20-Sekunden-Anfrage abgeschlossen ist, kommen die Antworten alle durch, aber beachten Sie, dass einige Anfragen, die sind nicht halten werden ...
So Fragen:
- Was zum Teufel ist hier los? Warum funktioniert es gut mit
NetTcpBinding
und nicht mitWSHttpBinding
arbeiten? - Warum das inkonsistente Verhalten?
- Was kann ich tun, um es zu beheben?
Hinweise:
- Es ist nicht auf dem Server sperren. Ich habe Breakpoints gesetzt und
!syncblk
verwendet und es meldet ständig, dass keine Sperren gehalten werden. - Es ist nicht mein Gewinde (NetTcpBinding sollte nicht anders funktionieren)
- Ich habe
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
Satz in dem app.config des Server - Der 20-Sekunden-Anruf auf einem Timer nur darauf wartet, ist es nicht die CPU oder Festplatte ist Dreschen oder Netzwerk
- Ich würde eine Lösung bevorzugen, die die Anwendung nicht re-architecting, um asynchrone Anrufe zu verwenden ... es ist ein großer Haufen von Legacy-Code, und ich will wirklich nicht mit Sachen herumalbern, die ich nicht ' ich verstehe nicht.
+1 Ausgezeichnetes Layout der Frage. –
Haben Sie dieses Problem jemals gelöst? Wenn ja, wie hast du es gelöst? – DivisionByZorro
Hinzugefügt eine Selbst-Antwort beschreibt unsere endgültige "Lösung" –