Frage

Ich habe ein Problem bemerkt, bei dem das Ereignis eines Socketasynceventargs erfüllt ist scheint aufzuhören zu schießen. Das gleiche SAEA kann ordnungsgemäß abfeuern und mehrmals im Pool ersetzt werden, aber schließlich werden alle Fälle aufhören zu schießen, und da der Code, der sie im Pool ersetzt, im Ereignishandler ist, leert der Pool.

Das folgende Umstände sind auch anscheinend auch wahr:

1) Es scheint nur dann zu sein, wenn eine serverseitige Socket Daten an einen der verbundenen Clients sendet. Wenn dieselbe Klasse als Client herstellt, scheint sie nicht zu fehlzuingen.

2) Es scheint unter hoher Belastung aufzutreten. Die Fadenzahl scheint sich zu kriechen, bis schließlich der Fehler auftritt.

3) Ein Testbohrgerät unter ähnlicher Stress scheint niemals zu falsch zu funktionieren. (Es sind nur 20 Nachrichten pro Sekunde, und das Test -Rig hat sich von 20.000 nachgewiesen)

Ich werde den ziemlich komplizierten Code nicht einfügen können, aber hier ist ein Beschreibung meines Codes:

1) Die Hauptinspiration ist Folgendes: http://vadmyst.blogspot.ch/2008/05/sample-code-for-tcp-server-using.html. Es wird angezeigt, wie Sie einen Fertigstellungsport mit einem Ereignis anschließen, wie Sie Nachrichten über die TCP -Verbindung in unterschiedlichen Größe erhalten und so weiter.

2) Ich habe einen Bytepuffer, in dem alle Saeas ein Stück haben, das sich nicht überlappt.

3) Ich habe einen Objektpool von SAEAS, der auf einer Blockierung basiert. Dies wirft, wenn der Pool zu lange leer ist.

4) Als Server behalte ich eine Sammlung von Sockets, die von der AcceptAsync -Funktion zurückgegeben werden, die vom Endpunkt des Clients indiziert wird. Ein einzelner Prozess kann eine Instanz sowohl als Server als auch als mehrere Instanzen als Clients verwenden (bilden ein Web). Sie teilen den Datenpuffer und den Pool von SAEAS.

Mir ist klar, dass es schwer ist, dies zu erklären; Ich habe es für einen ganzen Tag und eine ganze Nacht debuggen. Ich hoffe nur, dass jemand davon gehört hat oder nützliche Fragen oder Vorschläge hat.

Im Moment vermutet ich eine Art Fadenerschöpfung, was dazu führt, dass die Saeas nicht in der Lage sind, die Fertigstellung zu bezeichnen. Alternativ eine Art Pufferproblem auf dem ausgehenden Puffer.

War es hilfreich?

Lösung

Also ein weiterer Tag des Debuggens und schließlich habe ich eine Erklärung.

1) Die SAEAS feuerten das abgeschlossene Ereignis nicht ab, weil sie nicht mehr senden konnten. Dies zeigt, dass Wireshark auf das TCP -Fensterentleer zurückzuführen ist. (TCP Zerowindow)

2) Das TCP -Fenster entleerte sich, da die Netzwerkschicht ein Ereignis in den Stapel weitergab, der zu lange dauerte, dh es gibt keinen Produzenten/Verbraucher zwischen der Netzwerkschicht und der Benutzeroberfläche. Daher müsste das Netzwerk -OP auf das Zeichnen des Bildschirms warten, bevor das ACK gesendet wird.

3) Die Veranstaltung, die zu lange dauerte, war ein Bildschirmaufzug in einem Event -Handler auf der GUI. Das Test -Rig war ein Konsolenfenster (eines, das eingehende Nachrichten zusammenfasste). Deshalb verursachte es also kein Problem bei einer viel höheren Last. Es ist normal, den Bildschirm bei jeder Nachricht nicht neu zu zeichnen, aber dies geschah, weil das Projekt noch nicht ganz fertig ist. Die Neuausfahrtsrate wäre später festgelegt worden.

4) Die kurzfristige Lösung besteht einfach darin, sicherzustellen, dass keine GUIs die Show hochhält. Eine robustere Lösung könnte darin bestehen, einen Produzenten/Verbraucher auf der Netzwerkebene zu erstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top