使用StreamReader从MemoryStream中读取而不关闭VB.Net

时间:2016-07-22 16:21:31

标签: vb.net tcp stream garbage-collection

我正在尝试创建一个用于处理多个Tcp连接的类。问题是我在MemoryStream中写了从客户端发送的数据。我必须从流中读取第一行,看它是否包含“[ID]”。似乎一旦我尝试使用它来阅读它:

Using sr as new StreamReader(data_stream)
   If sr.readLine="[id]" then
      ' Code
   End If

End Using

它关闭了流。我甚至尝试创建一个dublicate(我不想要太多的dublicate,因为我将通过tcp发送大型数据,因此它将填充RAM)。然后我在一个事件中发送内存流。即使流是ByVal发送的,当我使用StreamReader时它仍然关闭它。我不想离开GC来处理未关闭的Stream Readers(我尝试了另一个由我制作的类 - 也用于Tcp-并且GC被连续多次调用......应用程序使用了27 MB因为dublicates的RAM - 我发送了多张图片)。是否可以使用缓冲区(字节数组)并保留内存流?或者我应该让GC为我做这个工作吗?

以下是该课程的一部分:

Sub receive_header(ar As IAsyncResult)
    received_size += client_stream.EndRead(ar)

    If received_size = 0 Then
        RaiseEvent Internal_Disconnected(New Exception("Connection closed normally"))
    Else
        If received_size < client_header_size Then
            client_stream.BeginRead(buffer, received_size, client_header_size - received_size, New AsyncCallback(AddressOf receive_header), client_stream)
        Else
            received_size = 0
            client_header = readHeader(buffer)

            Array.Clear(buffer, 0, client_header_size)

            client_stream.BeginRead(buffer, 0, buffer.Length, New AsyncCallback(AddressOf receive_data), client_stream)
        End If
    End If
End Sub
Sub receive_data(ar As IAsyncResult)
    received_size += client_stream.EndRead(ar)

    If received_size = 0 Then
        RaiseEvent Internal_Disconnected(New Exception("Connection closed normally"))
    Else
        data_stream.Write(buffer, 0, received_size)

        If received_size < client_header.PACK_SIZE Then
            'TODO: Here can be made an optimization
            ' Buffer has a length of client_stream.EndRead(ar). So take that instead of adding to received_size
            Array.Clear(buffer, 0, buffer.Length)

            client_stream.BeginRead(buffer, 0, buffer.Length, New AsyncCallback(AddressOf receive_data), client_stream)
        Else
            received_size = 0


            ' Send data to user if canSend
            If canSend Then
                data_stream.Position = 0

                ' If in this event I use stream reader it closes the main stream althought it is passed byVal
                RaiseEvent New_Message(Me, data_stream)
            End If

            ' Check first line
            data_stream.Position = 0

            Dim sr As New StreamReader(data_stream)
            If sr.ReadLine = "[ID]" Then
                canSend = True

                With client
                    .ID = sr.ReadLine.Split("=")(1)
                    .Computer_Name = sr.ReadLine.Split("=")(1)
                    .Win_Ver = sr.ReadLine.Split("=")(1)
                End With
            End If


            ' Reset
            data_stream.Close()
            data_stream = New MemoryStream

            Array.Clear(buffer, 0, buffer.Length)
            client_stream.BeginRead(buffer, 0, client_header_size, New AsyncCallback(AddressOf receive_header), client_stream)
        End If
    End If
End Sub

正如您在 receive_data 函数中看到的那样,我只有2048个字节来自缓冲区。如果消息较长,我会重复使用缓冲区,但不会在 data_stream 中保存数据之前。如何通过事件传递 data_stream 并在不关闭的情况下阅读它?

0 个答案:

没有答案