vb.netwinformsfilestream

Issue reading carriage return using FileStream


I'm having an issue in a Windows Forms VB.NET program when reading a carriage return, but only after the second read.

I've created an entire new project to focus only on the part that makes the program freeze and it's the same behavior.

It's fairly easy to recreate on your side (or not if it's related to my setup...).

File example :

A
B

Related code :

Using fichier As FileStream = New FileStream("first.txt", FileMode.OpenOrCreate)
    If fichier.CanRead() Then
        Dim contenu(100) As Byte

        fichier.Position = 0

        fichier.Read(contenu, 0, 100)

        TextBox1.Text = String.Empty

        Try
            For Each lettre As Byte In contenu
                TextBox1.Text += Chr(lettre)
            Next
        Catch ex As Exception

        End Try
    End If
End Using

First click on the button works, you get what's below in the TextBox :

"A" & vbCrLf & "B"

Second click on the button will make the program freeze. When I execute step-by-step it happens when Chr(13) is being added to TextBox1.Text. No exception risen.

I'm following a training PDF from 2013 got from a website because I wasn't able to find better. So I'm pretty sure there is a better way to read from a file and that's not what I'm interested in here.

I'd really like to understand what's happening with that code. Especially since it works well the first time.

I couldn't find a similar post and I'm not good enough with Diagnostic tools to figure it out on my own.

Thanks for your help,

L


Solution

  • Using a control as if it was a variable can cause performance problems if its properties are being changed rapidly - for example, just changing one character in its .Text property means that it needs to be re-rendered.

    Instead, it is better to do the intensive work separately and then do just one change to the control, so, for the code in the question, rather than:

    For Each lettre As Byte In contenu
        TextBox1.Text += Chr(lettre)
    Next
    

    you might do:

    Dim sb As New StringBuilder()
    For Each b In contenu
        sb.Append(Chr(b))
    Next
    
    TextBox1.Text = sb.ToString()
    

    Using a StringBuilder is usually better than concatenating a string when there are more than maybe 6–10 items to concatenate.