5 Stimmen

.NET Async Sockets: jeder Vorteil von SocketAsyncEventArgs über Begin/End in diesem Szenario?

Sockel hat diese neue asynchrone Methoden seit .NET 3.5 zur Verwendung mit SocketAsyncEventArgs (z. B. Socket.SendAsync() ), was den Vorteil hat, dass sie unter der Haube IO-Abschluss-Ports verwenden und die Notwendigkeit einer ständigen Zuweisung vermeiden.

Wir haben eine Klasse namens UdpStream mit einer einfachen Schnittstelle - nur StartSend und eine Abgeschlossen Veranstaltung. Es weist zwei SocketAsyncEventArgs zu, eines zum Senden und eines zum Empfangen. Das StartSend-Ereignis sendet einfach eine Nachricht mit SendAsync und wird etwa 10 Mal pro Sekunde aufgerufen. Wir verwenden das Ereignis Completed für die SocketAsyncEventArgs für den Empfang, und nachdem jedes Ereignis behandelt wurde, rufen wir ReceiveAsync auf, so dass eine Empfangsschleife entsteht. Auch hier empfangen wir etwa 10 Mal pro Sekunde.

Unser System muss bis zu 500 dieser UdpStream Objekte. Mit anderen Worten: Unser Server wird gleichzeitig mit 500 verschiedenen IP-Endpunkten kommunizieren.

Ich bemerke in den MSDN SocketAsyncEventArgs-Beispielen, dass sie N x SocketAsyncEventArgs zuweisen, eine für jede ausstehende Empfangsoperation, die Sie zu einem Zeitpunkt behandeln möchten. Mir ist nicht ganz klar, wie sich dies auf unser Szenario bezieht - es scheint mir, dass wir vielleicht nicht den Vorteil von SocketAsyncEventArgs erhalten, weil wir einfach einen pro Endpunkt zuweisen. Wenn wir mit 500 empfangenen SocketAsyncEventArgs enden, nehme ich an, dass wir keinen Nutzen daraus ziehen werden. Vielleicht erhalten wir noch einige Vorteile von IO Completion Ports?

  • Verwendet dieser Entwurf SocketAsyncEventArgs korrekt, wenn Skalierung auf 500?

  • Gibt es für den Fall, dass ein einziger "UdpStream" verwendet wird, eine Vorteil der Verwendung von SocketAsyncEventArgs gegenüber der älteren Begin/End-API?

10voto

Reed Copsey Punkte 536986

es scheint mir, dass vielleicht wir nicht den Vorteil der SocketAsyncEventArgs erhalten, weil wir einfach eine pro Endpunkt zuweisen. Wenn wir am Ende mit 500 erhalten SocketAsyncEventArgs ich vermute, wir werden keinen Nutzen erhalten.

Das ist immer noch ein großer Vorteil.

Wenn Sie das APM-Muster (Begin/End-Methoden) verwenden, wird jede einzelne BeginSend und jede BeginReceive zuweisen IAsyncResult Instanz. Das bedeutet, dass eine vollständige Zuweisung von Klassen/Objekten etwa 10.000 Mal pro Sekunde erfolgt (500*10 [Senden] + 500*10 [Empfangen]). Dies stellt eine große Menge an zusätzlichen Overhead im System, da es eine Menge von GC Druck hinzufügen wird.

Wenn Sie zu der neuen vorgeschlagenen Methode für Hochleistungs-Netzwerkanwendungen wechseln, müssen Sie die Speicherplätze im Voraus zuweisen. SocketAsyncEventArgs Instanzen (500) und sie wiederverwenden für jeden Methodenaufruf, wodurch der bei diesen Operationen entstehende GC-Druck beseitigt wird.

6voto

jgauffin Punkte 97446

Socket hat diese neuen asynchronen Methoden seit .NET 3.5 für die Verwendung mit SocketAsyncEventArgs (z. B. Socket.SendAsync()), Vorteile, die unter der Haube verwenden sie IO Abschluss Ports und vermeiden die Notwendigkeit zu halten Allokation.

Begin/End-Methoden verwenden ebenfalls IO Completion Ports.

Für den Fall, wo wir einen einzigen "UdpStream" in Gebrauch haben, gibt es irgendeinen Vorteil zur Verwendung von SocketAsyncEventArgs gegenüber der Verwendung der älteren Begin/End-API?

Imho sollten Sie bei dem bleiben, was Sie kennen, da Sie das Produkt schneller zum Laufen bringen werden. Aber ich würde auch eine strikte IO-Handling-Klasse erstellen, die sich um den Transport kümmert. Das macht es einfacher, auf das neue Modell zu wechseln, wenn sich die Transportleistung als Engpass erweist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X