Benutzerdefinierte WCF-Erweiterungen erzwingen die sequenzielle Ausführung gleichzeitiger Vorgänge

In diesem Artikel wird beschrieben, dass Clienttimeouts oder lange Wartezeiten auftreten können, da benutzerdefinierte WCF-Erweiterungen die sequenzielle Ausführung gleichzeitiger Vorgänge erzwingen und eine Lösung bereitstellen.

Ursprüngliche Produktversion:   Microsoft .NET Framework 4.5
Ursprüngliche KB-Nummer:   2907010

Problembeschreibung

Stellen Sie sich folgendes Szenario vor:

  • Sie haben den Windows Wcf-Dienst (Communication Foundation) für die Verarbeitung mehrerer gleichzeitiger Anforderungen konfiguriert.

  • Sie verfügen über benutzerdefinierte Implementierungen einer der folgenden WCF-Erweiterungen:

    • ServiceAuthenticationManager
    • ServiceAuthorizationManager
    • IDispatchMessageInspector
    • IDispatchOperationSelector
  • Diese Implementierungen sind rechenintensiv, oder sie verursachen gelegentlich lange Wartezeiten.

  • Gleichzeitige Dienstvorgänge scheinen sequenziell ausgeführt zu werden, oder clients timeout.

Wenn in diesem Szenario Clienttimeouts oder lange Reaktionszeiten auftreten, die nicht mit der Serverlast in diesem Szenario zusammenhängen, können Sie diese benutzerdefinierten WCF-Erweiterungen so verwenden, dass dieses Problem ausgelöst wird.

Darüber hinaus kann es vorkommen, dass eine Anforderung andere Anforderungen verzögert. Dann können viele Anforderungen plötzlich abgeschlossen werden, bevor eine andere Anforderung erneut andere Anforderungen verzögert. Sie können dieses Verhalten anzeigen, indem Sie den ServiceModelService Leistungsindikator "Aufrufe pro Sekunde" im Leistungsmonitor verwenden. Wenn dieses Verhalten auftritt, kann die Anzahl während der Ausführung des Erweiterungscodes auf Null fallen, selbst wenn mehrere gleichzeitige Anforderungen ausstehen. Wenn der Erweiterungscode die Steuerung an WCF zurückgibt, kehrt der Zähler zu seiner typischen Ebene zurück, bis die nächste Verzögerung im Erweiterungscode wieder auf Null fällt.

Ursache

Dieses Problem tritt auf, da WCF diese spezifischen Erweiterbarkeitspunkte synchron und frühzeitig in der Pipeline für die Nachrichtenverarbeitung aufruft. Verzögerungen bei diesen Erweiterungspunkten können diese Pipeline blockieren. Dadurch wird die gleichzeitige Ausführung von Dienstvorgängen verhindert. Nachrichten, die während dieser Zeit empfangen werden, werden in die Warteschlange eingereiht, werden jedoch erst gewartet, nachdem diese Erweiterungspunkte die Kontrolle an WCF zurückgegeben haben.

Dadurch werden die Dienstvorgänge nacheinander ausgeführt, nicht gleichzeitig. Jede Anforderung wartet in der Zeile, bis die vorherige die Ausführung dieser Erweiterungspunkte abgeschlossen hat. Wenn die Latenz hoch genug ist, können die letzten Anforderungen ein Timeout haben, während sie auf den Abschluss der früheren Anforderungen warten.

Hier sind die spezifischen Erweiterbarkeitsmethoden, die betroffen sind:

  • Microsoft .NET Framework 4.5 und .NET Framework 4.0:
    • ServiceAuthenticationManager.Authenticate()
  • .NET Framework .NET Framework 4.5, .NET Framework 4.0, .NET Framework 3.5 und .NET Framework 3.0:
    • ServiceAuthorizationManager.CheckAccessCore()
    • IDispatchMessageFormatter.AfterReceiveRequest()
    • IDispatchOperationSelector.SelectOperation()

Lösung

Verwenden Sie eine der folgenden Methoden, um dieses Problem zu beheben:

  • Minimieren Sie die Latenz dieser Erweiterbarkeitspunkte.
  • Verschieben Sie den Overhead mit hoher Latenz an eine andere Stelle in der Pipeline.
  • Verwenden Sie eine andere WCF-Bindung.

Es gibt einige gängige Methoden, die zu einer hohen Latenz aufgrund dieser Erweiterungspunkte führen können:

  • Zugreifen auf eine Datenbank, insbesondere auf einer anderen Ebene
  • Aufrufen anderer Dienste auf einer anderen Ebene
  • Verwenden einer großen Menge an Arbeitsspeicher oder Threads
  • Rechenintensive Arbeit

Wenn diese Arbeit mit hoher Latenz erforderlich ist, sollte sie aus diesen Erweiterungspunkten entfernt werden. Wenn diese Arbeit z. B. innerhalb des Dienstvorgangs selbst ausgeführt wird, lassen sie mehrere Vorgänge gleichzeitig ausführen.

Dieses Verhalten hängt möglicherweise auch von den Funktionen der Bindung ab, die für den Endpunkt verwendet wird. Zeigt z. B. BasicHttpBinding dieses Verhalten, während dies nicht der Fall WsHttpBinding ist.

References