开发者

Is there way to speed up displaying a lot of text in a winforms textbox?

开发者 https://www.devze.com 2023-01-29 10:29 出处:网络
Is there way to sp开发者_Python百科eed up displaying a lot of text in a winforms textbox? My application reads a file (which can be as large as 20MB) and then displays it to a textbox (TextBoxX.Text =

Is there way to sp开发者_Python百科eed up displaying a lot of text in a winforms textbox? My application reads a file (which can be as large as 20MB) and then displays it to a textbox (TextBoxX.Text = fileText;).

The process of displaying the text is extremely slow, it sometimes takes up to a few minutes. The problem is that this application is designed to show a lot of text in a file, quickly to the user.

Is there any way to do this faster? Maybe use some kind of caching?


I know this question is old at this time, but I would like to add information I consider may be helpful to others.

If you set WordWrap=false, the performance will improve dramatically in some cases. It will still wrap long lines when a max limit is reached. I tried some text 90K long which included a long chunk of Base64 data, and the response changed from 16 seconds to 2 seconds.


The Text property is evil if you like to put lot of text into a TextBox. Instead you should read the file in chunks and add them by using the AppendText() function.

If you go further and put your file read process into a BackgroundWorker that reads in the file line by line and then reports each line in ReportProgress, you could implement there the AppendText() and it should do everything much smoother.

Update

After some coding and testing i have to admit that the above described approach sounds good, but the TextBox needs so much rendering time after each AppendText() that this just doesn't work.

But if you have no problem about using 3rd party controls you should take a look at Scintilla.Net. It has no problems with big text files and performs really better in these cases.


In my case, I need to scan about 100~5000 files and show information of each files one by one.

Some improvements have been done:

  1. WordWrap=false (as @DDRider62 said)
  2. Use TextBox.AppendText() instead of Text (as @Oliver said).

And more, since the scanning of single files took only 7 milliseconds, I built a buffer to avoid calling AppendText() 140 times per second. It looked like this:

        const int DisplayIntervalInMilliseconds = 100;
        string buffer = null;
        var lastTimeUpdated = DateTime.Now;
        foreach (var fileName in fileNames)
        {
            progressBar?.ShowProgress(count++);
            var cppFile = new CodeFileCpp(fileName);
            buffer += cppFile.Show();

            var now = DateTime.Now;
            if (now - lastTimeUpdated <= new TimeSpan(
                0, 0, 0, 0, DisplayIntervalInMilliseconds))
            {
                continue;
            }
            textDisplayer.Append(buffer);
            buffer = string.Empty;
            lastTimeUpdated = now;
        }
        textDisplayer.Append(buffer);

The textDisplayer.Append calls the TextBox.AppendText(). Pay attention that we need to append the buffer again after the loop, because there is a big chance that the buffer is not empty when the loop stops.

At the beginning, with 845 files to scan, it cost me 2 minutes to reach about 500, and it became more and more slowly so I had to stopped it. Now with all the work above, it takes 2 seconds totally.


I think there is only one way - to build your own control (or maybe there is one) to display small parts of the text (like in far manager, when you open extreme large files) in your box.

You define a "window" - for example 500 letters and when you use scrollbar to change position you change body of yourtextbox and display another part of the text.


Have a look at the LockWindowUpdate function, don't forget to unlock once you've added the text to the textbox.

http://msdn.microsoft.com/en-us/library/dd145034%28v=vs.85%29.aspx


I think that a 20Mb file would have a visible delay even when opened through notepad.

Adding to the suggestion on reading chunks of data (which is the best option for large data.. like its proven on web downloads)..

you could open the text file in read mode as a filestream.. and then read 1mb or less of byte content in a loop .. and add the content to the textbox.

psuedocode:

while (not end of file) { string content = read 1024*1024 bytes from stream.. convert it into ascii encoding.

textbox.text += content

}


Having just run into this issue myself, another possible workaround is to use a RichTextBox. Counter-intuitively, considering how much more it can handle compared to a normal TextBox, setting the Text property of a RichTextBox to a very large string is virtually instantaneous.


Solution with minimal change in code will be to read the whole file contents into variable, then append "chunks" of the contents to the textbox in a loop calling Application.DoEvents() in each iteration.

You can show "Loading please wait..." message while it's still loading, the DoEvents call will ensure your application won't be "frozen" in the meanwhile.

0

精彩评论

暂无评论...
验证码 换一张
取 消