Loading large text (log file) into a text box without freezing up / hanging the form

Darren Rose 311 Reputation points
2022-02-13T18:41:49.803+00:00

I want to create a log viewer in my app to view log files create by my app (plain .txt files), they can be quite large.

I want to show them on screen.

I assume best control will be a simple multi-line text box?

How to load them without freezing up the form whilst it is loading all the lines.

Currently using below but as I say it does lockup form for a short while if log file is large

TextBox1.Text = System.IO.File.ReadAllText(filename)

Any better solutions.

Second question - any text boxes or other controls where I can show line numbers?

Thanks

Developer technologies VB
0 comments No comments
{count} votes

Accepted answer
  1. LesHay 7,141 Reputation points
    2022-02-14T17:28:36.553+00:00
        Private Sub RichTextBox1_VScroll(sender As Object, e As EventArgs) Handles RichTextBox1.VScroll
            If Not BackgroundWorker1.IsBusy AndAlso pointer < lines.Count Then BackgroundWorker1.RunWorkerAsync()
        End Sub
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Not BackgroundWorker1.IsBusy AndAlso pointer < lines.Count Then BackgroundWorker1.RunWorkerAsync()
        End Sub
    

3 additional answers

Sort by: Most helpful
  1. Darren Rose 311 Reputation points
    2022-02-14T19:51:34.737+00:00

    Found two other great solutions - which I wanted to share here for anyone else finding this question

    Fast Coloured Text Box (FCTB) - has a control for WinForms - works really quickly and very customizable with great demos

    https://github.com/PavelTorgashov/FastColoredTextBox

    https://www.nuget.org/packages/FCTB/

    ScintillaNET - which also has a control for WinForms - this loads large text files almost instantly and allows you to show numbering down left hand side

    https://github.com/jacobslusser/ScintillaNET

    https://github.com/robinrodricks/ScintillaNET.Demo

    https://www.nuget.org/packages/Scintilla.NET/

    1 person found this answer helpful.
    0 comments No comments

  2. LesHay 7,141 Reputation points
    2022-02-13T22:04:17.907+00:00

    Hi

    The time is mostly used by the interaction with whatever 'container' you are putting the text. I can read in a 135MB text file in less than 1 second, but more than a minute to put it into a TextBox or RichTextBox.

    The Form 'lockup' is easily overcome, using (say) a BackGroundWorker, which would load the text in the background keeping the UI responsive for the User.

    What is the largest file size you would expect to use?

    Try out this example to see if it helps - just change path to suit, and edit the block size (maybe a little experimentation with different sizes)

    173897-111.png

    ' Form1 with:  
    ' RichTextBox1,  Button1  
    ' and Label1  
      
    Option Strict On  
    Option Explicit On  
    Public Class Form1  
    	Dim lines() As String  
    	Dim pointer As Integer = 0  
      
    	' set blocksize to suit  
    	Dim blocksize As Integer = 10  
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load  
    		lines = IO.File.ReadAllLines("C:\Users\lesha\Desktop\freddy.txt")  
      
    		' read in first chunk  
    		BackgroundWorker1.RunWorkerAsync()  
      
    	End Sub  
    	Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork  
    		Dim current As Integer = pointer + blocksize  
    		Do  
    			Invoke(Sub() RichTextBox1.AppendText(lines(pointer) & vbCrLf))  
    			pointer += 1  
    		Loop Until pointer = current Or pointer = lines.Count  
    		Invoke(Sub() Label1.Text = pointer.ToString)  
    	End Sub  
    	Private Sub RichTextBox1_VScroll(sender As Object, e As EventArgs) Handles RichTextBox1.VScroll  
    		If pointer < lines.Count Then BackgroundWorker1.RunWorkerAsync()  
    	End Sub  
    	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click  
    		If pointer < lines.Count Then BackgroundWorker1.RunWorkerAsync()  
    	End Sub  
    End Class  
    

  3. LesHay 7,141 Reputation points
    2022-02-14T17:19:33.377+00:00

    Hi

    OK, sorry that my code is not of use. Maybe someone else will offer a more reliable solution that doesn't require any work on your part.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.