By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,122 Members | 2,053 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,122 IT Pros & Developers. It's quick & easy.

Fastest way to append text to a TextBox

P: n/a
VB.Net 2005 SP1
Windows Forms Application

What's the fastest way to append text to a [Rich]TextBox?

I have an application that monitors data written to text [log] files.
It needs to scan some fairly hefty files (typically ~15MB) and scanning
the file pulling out the rows I want (typically ~10,000 of them) takes
/comfortably/ under three seconds. In normal usage, this application
will "follow" the end of these files as they are written to, so it needs
to be able to scan [the end of] the file and update the screen in "real
time".

However if, as I find them, I take each of these lines and append them
to the end of a TextBox on a Form, the process slows to a crawl,
red-lines my CPU and, even if I limit the TextBox to just 30KB of text,
it takes over 90 seconds to complete.
(This will eventually be a RichTextBox because the output lines will
need to be colour-coded as well, but I'm trying to start simple).
So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?
OK, OK, normally, even /I'd/ be the first to say

"who /needs/ to see 10,000 lines of data?"

but, I can think of at least three of my users who will want [the
opportunity] to see every single one of them.

I have to say I was stunned at how fast VB.Net crunched its way through
the data, but if getting that data up onto the screen is going to be
/this/ slow, it's hardly worthwhile doing the "upgrade".

My "appending" code:

Private Sub AppendText(ByVal sText As String)
With Me.TextBox1
Dim iLen As Integer = .Text.Length + sText.Length

If (iLen >= (30000 * 1.1)) Then
Dim iTrimmer As Integer = iLen - 30000
Dim iPos As Integer = .Text.IndexOf(vbCrLf, iTrimmer)
.SelectionStart = 0
.SelectionLength = iPos + 1
.SelectedText = String.Empty
End If

.SelectionStart = .Text.Length
.SelectedText = sText & vbCrLf

.SelectionStart = .Text.Length

End With
End Sub

(Without the trimming bit, it's even more, /unbelievably/ slow; I got
fed up waiting after five minutes.)

Any suggestions?

TIA,
Phill W.
Apr 2 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Update the rtb in with batches of lines, not single lines. The performance
behavior you don't like will come with any control, eg updating a heavily
loaded list box one line at a time will crawl too.

"Phill W." wrote:
VB.Net 2005 SP1
Windows Forms Application

What's the fastest way to append text to a [Rich]TextBox?

I have an application that monitors data written to text [log] files.
It needs to scan some fairly hefty files (typically ~15MB) and scanning
the file pulling out the rows I want (typically ~10,000 of them) takes
/comfortably/ under three seconds. In normal usage, this application
will "follow" the end of these files as they are written to, so it needs
to be able to scan [the end of] the file and update the screen in "real
time".

However if, as I find them, I take each of these lines and append them
to the end of a TextBox on a Form, the process slows to a crawl,
red-lines my CPU and, even if I limit the TextBox to just 30KB of text,
it takes over 90 seconds to complete.
(This will eventually be a RichTextBox because the output lines will
need to be colour-coded as well, but I'm trying to start simple).
So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?
OK, OK, normally, even /I'd/ be the first to say

"who /needs/ to see 10,000 lines of data?"

but, I can think of at least three of my users who will want [the
opportunity] to see every single one of them.

I have to say I was stunned at how fast VB.Net crunched its way through
the data, but if getting that data up onto the screen is going to be
/this/ slow, it's hardly worthwhile doing the "upgrade".

My "appending" code:

Private Sub AppendText(ByVal sText As String)
With Me.TextBox1
Dim iLen As Integer = .Text.Length + sText.Length

If (iLen >= (30000 * 1.1)) Then
Dim iTrimmer As Integer = iLen - 30000
Dim iPos As Integer = .Text.IndexOf(vbCrLf, iTrimmer)
.SelectionStart = 0
.SelectionLength = iPos + 1
.SelectedText = String.Empty
End If

.SelectionStart = .Text.Length
.SelectedText = sText & vbCrLf

.SelectionStart = .Text.Length

End With
End Sub

(Without the trimming bit, it's even more, /unbelievably/ slow; I got
fed up waiting after five minutes.)

Any suggestions?

TIA,
Phill W.
Apr 2 '08 #2

P: n/a
let me ask this....

10,000 lines in 3 seconds ... that is 3,333 per second ... and you want this
real time ... why? I have yet to see a speed reader achive this type of
performance.

Write logical blocks or write to text control every second.

When you update a 'control' there is much more going on than simple string
concatinaction -the visual part of the process must be considered ... and
so on.
Jeff.

"Phill W." <p-.-a-.-w-a-r-d-@-o-p-e-n-.-a-c-.-u-kwrote in message
news:fs**********@south.jnrs.ja.net...
VB.Net 2005 SP1
Windows Forms Application

What's the fastest way to append text to a [Rich]TextBox?

I have an application that monitors data written to text [log] files. It
needs to scan some fairly hefty files (typically ~15MB) and scanning the
file pulling out the rows I want (typically ~10,000 of them) takes
/comfortably/ under three seconds. In normal usage, this application will
"follow" the end of these files as they are written to, so it needs to be
able to scan [the end of] the file and update the screen in "real time".

However if, as I find them, I take each of these lines and append them to
the end of a TextBox on a Form, the process slows to a crawl, red-lines my
CPU and, even if I limit the TextBox to just 30KB of text, it takes over
90 seconds to complete.
(This will eventually be a RichTextBox because the output lines will need
to be colour-coded as well, but I'm trying to start simple).
So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?
OK, OK, normally, even /I'd/ be the first to say

"who /needs/ to see 10,000 lines of data?"

but, I can think of at least three of my users who will want [the
opportunity] to see every single one of them.

I have to say I was stunned at how fast VB.Net crunched its way through
the data, but if getting that data up onto the screen is going to be
/this/ slow, it's hardly worthwhile doing the "upgrade".

My "appending" code:

Private Sub AppendText(ByVal sText As String)
With Me.TextBox1
Dim iLen As Integer = .Text.Length + sText.Length

If (iLen >= (30000 * 1.1)) Then
Dim iTrimmer As Integer = iLen - 30000
Dim iPos As Integer = .Text.IndexOf(vbCrLf, iTrimmer)
.SelectionStart = 0
.SelectionLength = iPos + 1
.SelectedText = String.Empty
End If

.SelectionStart = .Text.Length
.SelectedText = sText & vbCrLf

.SelectionStart = .Text.Length

End With
End Sub

(Without the trimming bit, it's even more, /unbelievably/ slow; I got fed
up waiting after five minutes.)

Any suggestions?

TIA,
Phill W.

Apr 2 '08 #3

P: n/a
Phill W. wrote:
>

So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?

' How about 10,000 lines, 5 seconds:

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim n As Integer
Dim s As String = "Hello, World, how is it going these days, " _
+ "is this quick enough for you?" + vbCrLf

Dim sb As New System.Text.StringBuilder

Dim t As Date = Now

With Me.TextBox1
For n = 1 To 10000
sb.Append(n.ToString("0000") + " ")
sb.Append(s)
If n Mod 500 = 0 Then
.Text = sb.ToString
.SelectionStart = .Text.Length
.SelectedText = " "
Me.Text = n.ToString
My.Application.DoEvents()
End If
Next n
.Text = sb.ToString
.SelectionStart = .Text.Length
.SelectedText = " "
Me.Text = "Done: " + (Now - t).TotalSeconds.ToString("#,0.00")
End With

End Sub
Apr 3 '08 #4

P: n/a
Phill,

You tell us about multiple lines while your code is in my idea for a single
string

First try to find out what makes the delay, is it about the writing to the
screen, or the creation of the added text.

As it is about the latter, then try a stringbuilder in between to create a
strings which ends with VBCRLF (probably automaticly because you retrieve
strings)

Cor

Apr 3 '08 #5

P: n/a
Have you tried just setting the text, not setting the selection ? Typically
setting selections is incredibly slow. Sometimes you can speed things up by
disabling the control, but that unusually also adds another lot of flicker.
For the RichTextBox, I use the COM interfaces and set the textranges.

"Phill W." <p-.-a-.-w-a-r-d-@-o-p-e-n-.-a-c-.-u-kwrote in message
news:fs**********@south.jnrs.ja.net...
VB.Net 2005 SP1
Windows Forms Application

What's the fastest way to append text to a [Rich]TextBox?

I have an application that monitors data written to text [log] files. It
needs to scan some fairly hefty files (typically ~15MB) and scanning the
file pulling out the rows I want (typically ~10,000 of them) takes
/comfortably/ under three seconds. In normal usage, this application will
"follow" the end of these files as they are written to, so it needs to be
able to scan [the end of] the file and update the screen in "real time".

However if, as I find them, I take each of these lines and append them to
the end of a TextBox on a Form, the process slows to a crawl, red-lines my
CPU and, even if I limit the TextBox to just 30KB of text, it takes over
90 seconds to complete.
(This will eventually be a RichTextBox because the output lines will need
to be colour-coded as well, but I'm trying to start simple).
So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?
OK, OK, normally, even /I'd/ be the first to say

"who /needs/ to see 10,000 lines of data?"

but, I can think of at least three of my users who will want [the
opportunity] to see every single one of them.

I have to say I was stunned at how fast VB.Net crunched its way through
the data, but if getting that data up onto the screen is going to be
/this/ slow, it's hardly worthwhile doing the "upgrade".

My "appending" code:

Private Sub AppendText(ByVal sText As String)
With Me.TextBox1
Dim iLen As Integer = .Text.Length + sText.Length

If (iLen >= (30000 * 1.1)) Then
Dim iTrimmer As Integer = iLen - 30000
Dim iPos As Integer = .Text.IndexOf(vbCrLf, iTrimmer)
.SelectionStart = 0
.SelectionLength = iPos + 1
.SelectedText = String.Empty
End If

.SelectionStart = .Text.Length
.SelectedText = sText & vbCrLf

.SelectionStart = .Text.Length

End With
End Sub

(Without the trimming bit, it's even more, /unbelievably/ slow; I got fed
up waiting after five minutes.)

Any suggestions?

TIA,
Phill W.
Apr 3 '08 #6

P: n/a
Steve Gerrard wrote:
Phill W. wrote:
>>
So, how can I get these lines into my TextBox /faster/?

Or, rather, why is updating the control /so/ slow, compared to hacking
strings around in memory?


' How about 10,000 lines, 5 seconds:
<snip>

Steve,

/Very/ nice!

If I truncate the StringBuilder after it's transferred its data into the
TextBox, it's even faster still (your 10,000 lines display in under a
second)!
OK, I may not get all the benefit of this (my colour coding the output
means I'll have to group lines of the /same/ colour together into a
single RichTextBox update) but, even so, it's hugely faster than before.

Many Thanks,
Phill W.
Apr 3 '08 #7

P: n/a
Cor Ligthert[MVP] wrote:
You tell us about multiple lines while your code is in my idea for a
single string
You are correct. The program would normally only deal with a handful of
lines but, when the servers get very heavily loaded, the current version
of this program (in VB6) gets swamped by the amount of incoming data.
First try to find out what makes the delay, is it about the writing to
the screen, or the creation of the added text.
Dealing with the lines as Strings is lightning fast; it's adding them
sequentially to the TextBox that slows to a crawl.
As it is about the latter, then try a stringbuilder in between to create
a strings which ends with VBCRLF (probably automaticly because you
retrieve strings)
I keep forgetting how quick StringBuilders are.

Batching the [TextBox] changes together improves things dramatically.

Regards,
Phill W.
Apr 3 '08 #8

P: n/a
Bill McCarthy wrote:
Have you tried just setting the text, not setting the selection ?
For a TextBox (all the same colour) I've tried this and it's a lot
faster. For the finished application, though, I need to use a
RichTextBox so that I can colour-code the displayed lines. If I set the
Text property on one of those, I lose all the previous colouration.
Typically setting selections is incredibly slow. Sometimes you can
speed things up by disabling the control, but that unusually also adds
another lot of flicker.
I hadn't thought of that, but then I'd rather not add the flickering
either. Unless I can sell it as a "feature"... ;-)
For the RichTextBox, I use the COM interfaces and set the textranges.
Can you tell me more? Or where to look?

Would these interfaces work even with the supplied [.Net] RichTextBox
Control? Or is /that/ just a wrapper around the underlying COM one?

Regards,
Phill W.
Apr 3 '08 #9

P: n/a

"Phill W." <p-.-a-.-w-a-r-d-@-o-p-e-n-.-a-c-.-u-kwrote in message
news:ft**********@south.jnrs.ja.net...
Bill McCarthy wrote:
>Have you tried just setting the text, not setting the selection ?

For a TextBox (all the same colour) I've tried this and it's a lot faster.
For the finished application, though, I need to use a RichTextBox so that
I can colour-code the displayed lines. If I set the Text property on one
of those, I lose all the previous colouration.
>Typically setting selections is incredibly slow. Sometimes you can speed
things up by disabling the control, but that unusually also adds another
lot of flicker.

I hadn't thought of that, but then I'd rather not add the flickering
either. Unless I can sell it as a "feature"... ;-)
>For the RichTextBox, I use the COM interfaces and set the textranges.

Can you tell me more? Or where to look?

Would these interfaces work even with the supplied [.Net] RichTextBox
Control? Or is /that/ just a wrapper around the underlying COM one?
Download the VB Snippet Editor. I use the COM interfaces of the .NET
richtextbox in that to color as you type. You may find it provides much of
the code colouring you are after.
http://www.billmccarthy.com/Projects...r/default.html


Apr 3 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.