3 Stimmen

Warum kann ich nicht das WaitHandle von Socket.BeginSend verwenden, um auf den Abschluss der Operation zu warten?

Ich habe den folgenden Code verwendet, um Daten asynchron zu senden, aber ich habe bemerkt, dass die Verwendung von WaitOne im AsyncWaitHandle, das ich von asyncRes wartet überhaupt nicht. Ich habe MSDN überprüft und es sagt, ich sollte ein ManualResetEvent verwenden.

...
var asyncRes = _socket.BeginSend(encodedFrame, 0, encodedFrame.Length, SocketFlags.None, sendCallback, _socket);
...
var success = asyncRes.AsyncWaitHandle.WaitOne(_timeout, true);
...

 private void sendCallback(IAsyncResult ar)
 {
     _socket.EndSend(ar);            
 }

MSDN sagt auch in IAsyncResult:

AsyncWaitHandle: Ruft ein WaitHandle ab, das verwendet wird, um auf den Abschluss einer asynchronen Operation zu warten.

Warum kann ich sie also nicht für diesen Zweck verwenden?

Ich danke Ihnen.

0 Stimmen

Möglicherweise tritt die Zeitüberschreitung auf?

0 Stimmen

Nö. Die Zeitüberschreitung tritt nicht auf

3voto

Hans Passant Punkte 894572

Ich bin mir nicht sicher, ob ich das Problem richtig verstehe. Aber das ist ein normales Verhalten. BeginSend bedeutet "dies asynchron tun, wenn müssen Sie ". Das muss nicht sehr oft der Fall sein. In vielen Fällen kann der Sendevorgang synchron abgeschlossen werden, da im Kernel-Speicherpool genügend Platz für die Speicherung der Bytes vorhanden ist. Dazu ist nur eine sehr schnelle Speicher-zu-Speicher-Kopie erforderlich, und die überlappende E/A-Übertragung wird sofort abgeschlossen.

Ein weiteres gutes Beispiel hierfür ist FileStream.BeginWrite(), das in den Dateisystem-Cache schreibt. Normalerweise müssen Sie mehr als ein Gigabyte schreiben, bevor der Cache voll ist und Zeit benötigt.

Wie dem auch sei, unter diesen Umständen kehrt der WaitOne()-Aufruf sofort zurück und verwendet nicht die Zeitüberschreitung. Raymond Chen hat gerade hat kürzlich darüber gebloggt . Aus der Sicht einer nativen API, aber das ist, was hier verwendet wird. Ich glaube nicht, dass Sie hier ein echtes Problem haben, nur Windows arbeitet effizient.

1voto

Hogan Punkte 65759

Wenn Sie den 2. Parameter auf true setzen, bedeutet das, dass Sie nicht warten wollen. Setzen Sie den 2. Parameter auf false und Sie sollten das gewünschte Ergebnis sehen.

Indem Sie den 2. Parameter auf true setzen, sagen Sie im Grunde "Abbruch".

1voto

John Leidegren Punkte 57871

Weil Sie es nicht sollen?

Die Konvention Begin/End async ist für die paarweise Verwendung gedacht. Dieses Beispiel ist vielleicht zu einfach, um zu veranschaulichen, warum man es so machen sollte, aber Tatsache ist, dass man es nicht so machen muss, man kann es auch so machen.

var ar = _socket.BeginSend(encodedFrame, 0, encodedFrame.Length, SocketFlags.None);
//...
_socket.EndSend(ar); // this is a blocking operation

Ich sehe keinen Sinn in der Verwendung von asynchronen IO, wenn Sie am Ende sowieso blockieren...

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