Gibt es eine Alternative in C # System.IO.BufferedStream?
-
23-08-2019 - |
Frage
Ich erhalte die Folge Ausnahme:
System.NotSupportedException : This stream does not support seek operations.
at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
at System.IO.BufferedStream.FlushRead()
at System.IO.BufferedStream.WriteByte(Byte value)
Der folgende Link zeigen, dass dies ein bekanntes Problem für Microsoft ist. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback. aspx? FeedbackID = 273.186
Dieses stacktrace zeigt 2 Dinge:
- Die System.IO.BufferedStream etwas absurd Zeiger bewegen Operation tun. Ein BufferedStream sollte die zugrunde liegenden Stream-Puffer und nicht mehr. Die Qualität des Puffers wird schlecht sein, wenn es eine solche gibt Betrieb suchen.
- Es wird nie mit einem Strom stabil arbeiten, die nicht unterstützen suchen.
Gibt es Alternativen? Habe Ich brauche einen Puffer zusammen mit einem Network in C # oder ist dies bereits gepuffert.
Edit:. Ich mag einfach die Anzahl der Lese reduzieren / Schreib Anrufe an den zugrunde liegenden Socket-Stream
Lösung
Die Lösung ist zwei unabhängige BufferedStream
s zu verwenden, eine zum Empfangen und einen für das Senden. Und vergessen Sie nicht in geeigneter Weise das Senden BufferedStream
zu spülen.
Seit 2018 selbst scheint es schwierig, eine befriedigende Antwort auf diese Frage zu bekommen, zum Wohle der Menschheit, hier sind meine zwei Cent:
Die NetworkStream
ist auf der OS-Seite gepuffert. Doch das bedeutet nicht, es gibt keine Gründe, auf der .net Seite zu puffern. TCP verhält sich gut auf Write-Read (Wiederholung), aber Ständen auf Write-Write-Read wegen verspäteter ack, etc, etc.
Wenn Sie, wie ich, ein Bündel von sub-par-Protokoll-Code haben in das einundzwanzigste Jahrhundert zu nehmen, möchten Sie puffern.
Alternativ , wenn Sie auf die oben bleiben, können Sie auch nur Puffer liest / RCVs oder nur schreibt / Sends, und verwenden Sie die NetworkStream
direkt für die andere Seite, je nachdem, wie gebrochen, welcher Code ist . Sie müssen nur konsequent sein!
Was BufferedStream
docs machen scheitern völlig klar ist, dass Sie nur Schalter Lesen und Schreiben, wenn Ihr Strom seekable ist . Dies liegt daran, es puffert liest und schreibt im gleichen Puffer. BufferedStream
einfach nicht gut funktioniert für NetworkStream
.
Wie Marc wies darauf hin, die Ursache für diese Lahmheit ist die Verschmelzung von zwei Strömen in ein Network, die nicht ein .net die größten Design-Entscheidungen ist.
Andere Tipps
Der Network bereits gepuffert. Alle Daten, die empfangen wird, wird in einem Puffer gehalten wartet auf Sie, es zu lesen. Anrufe zu lesen entweder sehr schnell sein, oder blockiert warten auf Daten vom anderen Peer im Netzwerk empfangen werden, ein BufferedStream nicht in jedem Fall zu helfen.
Wenn Sie über die Sperrung betroffen sind, dann können Sie sehen die zugrunde liegende Socket nicht blockierenden Modus umgeschaltet wird.
Ein BufferedStream
einfach wirkt, um die Anzahl der Lese- / Schreib-Anrufe an den zugrunde liegenden Stream zu reduzieren (die IO / Hardware gebunden sein kann). Es kann nicht liefern sucht Fähigkeit (und in der Tat, Pufferung und die Suche nach ist in vielerlei Hinsicht im Gegensatz zu ihnen).
Warum brauchen Sie suchen? Kopieren Sie vielleicht den Strom zu etwas seekable ersten - einem MemoryStream
oder FileStream
-. dann tun Sie Ihre eigentliche Arbeit aus diesen zweiten, seekable Strom
Sie haben einen bestimmten Zweck im Sinne? Ich kann in der Lage sein, mehr entsprechende Optionen mit mehr Details vorschlagen ...
Insbesondere: beachten Sie, dass NetworkStream
eine Kuriosität ist - mit den meisten Bächen, Lesen / Schreiben auf dem gleichen physikalischen Strom beziehen; jedoch ein NetworkStream
stellt tatsächlich zwei völlig voneinander unabhängige Rohre; Lesen und Schreiben sind völlig unabhängig. Ebenso können Sie nicht in Bytes suchen, die bereits an Ihnen vorbei Reißverschluss haben ... Sie können Überspringen Daten, aber das ist besser, indem Sie ein paar Read
opdrations und Verwerfen der Daten erfolgen.