1

私はアプリケーション用の新しいバッファリングプロセッサに取り組んでおり、ProtobufDeserialize*メソッドを見直し、次のコードを使用して調査しています。以前のバージョンでは、前に独自のTypeIdentifierとLengthPrefixがあり、デシリアライズするフルブロック。テストのために、networkStreamの読み取りを、ディスクに書き込まれたファイルからのランダムな長さのチャンクの読み取りに置き換えました。SerializeWithLengthPrefix()

しかし、mDatabufferをトラバースすると、EndOfStreamExceptionスローされます。これは大したことではありません。Deserialize呼び出しを介して完全に処理するデータの「完全な」ブロックがあるという保証はないため、これを正しく実行していることを確認したかっただけです。私は最初にTryReadLengthPrefixを実行していましたが、これはよりクリーンなようです。

Public Sub New(ByVal maximumPacketSize As Integer)
    mMaxSize = maximumPacketSize
    mDataBuffer = New MemoryStream()
    mTypeResolver = AddressOf PacketTypeResolver
End Sub

Public Sub ProcessBuffer(ByVal theData() As Byte, offset As Integer, 
                         ByVal bytesToRead As Integer)
    'append the data we have just received into our StreamBuffer so we can 
    '"move back" if we hit the end of stream whilst Deserializing
    mDataBuffer.Seek(0, SeekOrigin.End)
    mDataBuffer.Write(theData, offset, bytesToRead)
    mDataBuffer.Seek(0, SeekOrigin.Begin)

    While mDataBuffer.Position < mDataBuffer.Length
        Dim currentPosition As Integer = CType(mDataBuffer.Position, Integer)
        Try
            Dim p As Object = Nothing
            If Serializer.NonGeneric.TryDeserializeWithLengthPrefix(mDataBuffer, 
                          PrefixStyle.Base128, mTypeResolver, p) Then
                If GetType(BasePacket).IsAssignableFrom(p.GetType) Then
                    Dim bufferedPacket As BasePacket = CType(p, BasePacket)
                    ''''Do stuff with the packet.
                End If
            End If
        Catch ex As EndOfStreamException
            Dim tmpData As New MemoryStream()
            tmpData.Write(mDataBuffer.GetBuffer(), currentPosition, 
                          CType(mDataBuffer.Length - currentPosition, Integer))
            mDataBuffer.Dispose()
            mDataBuffer = tmpData
            Exit While
        Catch ex As Exception
            Debug.Print(ex.GetType.Name & "---" & ex.Message)
            Throw
        End Try
    End While
End Sub 

(脇)学習のために、内部で例外をキャッチしないというAPI設計の決定について疑問に思っていますTryDeserializeWithLengthPrefix

4

1 に答える 1

0

Tryinは、TryDeserializeWithLengthPrefix「問題がある場合は黙って諦める」ではなく、「ストリームから別のオブジェクトを取得しようとしますが、EOFが自然な位置(オブジェクト間)にある場合はfalseを返します」です。データが空ではないが不完全であるか、無効である場合:それでも通知されます。うるさい。

データを読んでいて、完全なオブジェクトがあるかどうかわからない場合は、次のいずれかを言います。

  • 独自のフレーミングプロトコルを作成する、または
  • TryReadLengthPrefix必要な長さを計算し、その量のデータをバッファリングするために使用します
于 2013-02-19T05:03:15.400 に答える