Time Critical Process in .NET

C

Charles Law

Hi Jay

I decided to test a theory ... here are some timings for updating a ListView
vs a RichTextBox (all timings in seconds)

Updates ListView RichTexBox ListView (no refresh)
100 0.5 0.28 ~0
1,000 5.42 4.0 0.25
10,000 52 197 2.56

I think this bears out the theory that the rich text box slows down as it
becomes filled up. The ListView update time is pretty linear, and for a
small number of updates is slower than the rich text box. The rich text box,
however, becomes abysmally slow as one adds a lot of text, ergo the ListView
is favourite. If one does not refresh the ListView after each update (not
possible with the RTB) then it is even quicker.

I think I will pursue the ListView approach :)

Charles
 
G

Guest

Your problems seems to be basically this:

Your rich edit UI update is too sloooow. BeginInvoke queues up calls to
maintain thread safety. The best solution IMHO is the "polling" technique I
suggested earlier.

1) Worker thread SyncLocks a stack and pushes stuff into it.
2) UI Timer set at a reasonable interval (1 second maybe) SyncLocks the
stack, pops stuff out (*without* updating the UI I may add!) and lets go of
the SyncLock and then updates the UI... very nice, quick, and elegant. Much
better than updating the UI in realtime and on-demand... which apparently is
not working the way you want it to.
3) Everyone is happy. At most the UI is a second or so behind the
workthread's actual status.
 
G

Guest

The RichEdit box is slow because of the "Immutable String" factor.
string = string + newString becomes exponentially slower on each iteration.

1) Use the list view as you have already noted. But that's annoying when you
want to let the user copy and paste portions of the status.
or
2) Find a way to optimize the RichEdit control by passing your ENTIRE
contents with embedded RTF tags... rather than using its traditional
properties to manipulate its text selections. That way you can keep your
status messages in a stringbuilder... which is infinitely faster than the
update-as-go method that you have chosen.
or
3) Write your own usercontrol that basically just "writes and forgets",
using a StringBuilder, DrawString, maybe a Scrollbar control, and some smart
code. It's not hard at all.
 
C

Charles Law

I have been experimenting some more, and have created a sample that queues
updates for a timer. The timer polls every second, and if it finds messages
in the queue it locks the queue, removes them all to an array, and unlocks
the queue. It then writes the messages to the rich text box and exits.

The queue is filled by a thread that just loops 1000 times, each time
locking the queue, adding a message and releasing the lock. So far so good.

If the FillQueue process is allowed to loop freely, it fills the queue in no
time at all (< 1 second). The timer then fires and takes 5 seconds to write
all the messages to the rich text box.

If the FillQueue process has a Sleep(20) in it (which is more representative
of my real-world scenario), then it takes 31 seconds to fill the queue, and
the timer function puts the messages on the screen (in a burst every
second), completing within 1 second of the FillQueue process finishing.

My second sample uses BeginInvoke. A class is created and its DoStuff method
is run on a new thread. DoStuff loops 1000 times, raising an event each time
round the loop. The event handler uses BeginInvoke to marshal to a function
that writes a message to a rich text box.

If DoStuff loops freely, it completes the loop in < 1 second. The screen
updates finish 5 seconds later.

If the DoStuff loop contains a Sleep(20), then it takes 31 seconds to
complete the loop, and the screen updates finish at exactly the same time.

From this simple test, it would seem to me that there is actually nothing to
choose between the two methods where speed is concerned. I haven't tried the
test with a loop count of 10,000, but I suspect that the results will be
comparable, and that the overriding issue will be the degradation of
performance of the rich text box as it fills up, as indicated by my earlier
test.

Following on from your other reply, I take the point about a listview
limiting the user's ability to copy sections of the output. The listview
also doesn't output as rtf, which is currently a nice feature because I can
retain the colour coding of the output. If there were a way of converting a
memory stream to rtf then that would be nice.

With regard to maintaining the rtf in a string builder, I have looked at
hand crafting rtf and it seems a lot to get to grips with. It also isn't as
generic a solution as I would like. I will look at this further though.

The idea of creating my own control has its appeal, because then I would
have total control. I will have a quick play and see where I get to.

Thanks.

Charles
 
C

Cor Ligthert

Charles,

Your listview is of course your solution.

However reading this I get the idea that a solution could have been.

Use a mainthread that updates your rtfbox.

Use a workerthread that gets assynchronous the information from the
workerthreads and passes that in whatever way assynchronous to the updating
thread.

Use your worker threads.

Tell me what is wrong in this theoretical model.

:)

Cor
 
C

Charles Law

Cor

I'm not sure I follow you entirely.
Use a mainthread that updates your rtfbox.

Do you mean as distinct from the UI thread? If it is, it will always have to
marshal back to the UI thread, so have I gained anything here?
Use a workerthread that gets assynchronous the information from the
workerthreads and passes that in whatever way assynchronous to the
updating thread.

This sounds like the queue sample I tried.
Use your worker threads.

?

Charles
 
C

Cor Ligthert

Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of your
RTFBox go smooth without any waiting in a seperated thread. Collect the
information for that in another tier as well in a seperated thread. And let
the worker tiers get the information for the last in as well seperated
threads.

This I can tell of course only now because we did not know that the RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
C

Charles Law

Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I am
probably outputting too much information in the first instance. I know that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I am
reminded of a similar situation put to me recently by a client. My answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed my own
advice.

I'm going to cache the large amount of output generated by the worker thread
and just output headings. If the user wishes to get more detail I will load
it when requested, in one hit. Nice and quick. I will also allow the entire
output to be saved, at which time I can generate the rtf. [I'm still looking
for a neat in-memory rtf generator. Maybe the rich text box will do it w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles
 
G

Guest

Good job testing out all of our flakey ideas. This was a very interesting and
enlightening thread.

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties to
set your formatting?
This is your bottleneck I take it as it will exponentially become slower as
the text increases. Have you taken a look at the RichTextBox's RTF property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes that
you would just dump into the control in one swoop (Text=sb.ToString() )

RTF codes aren't that difficult... it's a lot like HTML... check out this
link to get you started:
http://msdn.microsoft.com/library/d...tersInBoldInRichTextBoxControlVisualBasic.asp


Charles Law said:
Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I am
probably outputting too much information in the first instance. I know that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I am
reminded of a similar situation put to me recently by a client. My answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed my own
advice.

I'm going to cache the large amount of output generated by the worker thread
and just output headings. If the user wishes to get more detail I will load
it when requested, in one hit. Nice and quick. I will also allow the entire
output to be saved, at which time I can generate the rtf. [I'm still looking
for a neat in-memory rtf generator. Maybe the rich text box will do it w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles


Cor Ligthert said:
Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of your
RTFBox go smooth without any waiting in a seperated thread. Collect the
information for that in another tier as well in a seperated thread. And
let the worker tiers get the information for the last in as well seperated
threads.

This I can tell of course only now because we did not know that the RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
J

Jay B. Harlow [MVP - Outlook]

Cor & CMM,
This I can tell of course only now because we did not know that the RTFbox
was the bottleneck.
I'm not convinced the bottleneck is the RTF box per se! Yes the ListView is
faster then the RTF Box, but that does not prove that the RTFBox is the
bottle neck!

The bottleneck may be the interop marshalling from .NET world to the Win32
RTF Textbox world. In which case both the RTFBox & the ListView will have a
problem as both are based on "native" Win32 controls.

The bottleneck may be the GC!

The bottleneck may actually be the way Charles' program is interacting with
memory.

The bottleneck may be some unrelated program that happens to be running.

The bottleneck may be some unforseen disk access, such as page swapping.

The bottleneck may be any number of other things...

Hence my suggestion to use CLR Profiler & other tools to try to accurately
identify where specifically the bottle neck is.

Or at the very least two methods & see which is faster. However I have seen
where one method may be faster for small number and/or size of objects,
suddenly becomes painfully slow for large number and/or size of objects...

As Charles initially stated "The problem I have is that sometimes, for no
apparent reason, a step in my process takes an inordinate amount of time,
e.g 2.5 seconds instead of perhaps 300 ms." The "sometimes, for no apparent
reason" would suggest to me that it is not specifically the RTF or the
BeginInvoke, although it could be.

In other words BeginInvoke & the RTF Box are both still suspects, however
the jury (CLR Profiler) has not convicted them of any crime.

Just a thought
Jay
 
G

Guest

Correction: .Rtf = sb.ToString()

CMM said:
Good job testing out all of our flakey ideas. This was a very interesting and
enlightening thread.

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties to
set your formatting?
This is your bottleneck I take it as it will exponentially become slower as
the text increases. Have you taken a look at the RichTextBox's RTF property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes that
you would just dump into the control in one swoop (Text=sb.ToString() )

RTF codes aren't that difficult... it's a lot like HTML... check out this
link to get you started:
http://msdn.microsoft.com/library/d...tersInBoldInRichTextBoxControlVisualBasic.asp


Charles Law said:
Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I am
probably outputting too much information in the first instance. I know that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I am
reminded of a similar situation put to me recently by a client. My answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed my own
advice.

I'm going to cache the large amount of output generated by the worker thread
and just output headings. If the user wishes to get more detail I will load
it when requested, in one hit. Nice and quick. I will also allow the entire
output to be saved, at which time I can generate the rtf. [I'm still looking
for a neat in-memory rtf generator. Maybe the rich text box will do it w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles


Cor Ligthert said:
Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of your
RTFBox go smooth without any waiting in a seperated thread. Collect the
information for that in another tier as well in a seperated thread. And
let the worker tiers get the information for the last in as well seperated
threads.

This I can tell of course only now because we did not know that the RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
G

Guest

Agreed. It seems likely Charles probably has *multiple* bottlenecks
actually.... (I think) the richedit control being the most obvious and the GC
(lots of New Object instantiation / releasing, etc) being the more subtle one.
 
C

Charles Law

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties
to
set your formatting?

The actual code is below (TestResults is the rich text box)

<code>
Private Sub UpdateStatus(ByVal s As String)

Dim selectStart As Integer

With TestResults
.SuspendLayout()

.Focus()

selectStart = .TextLength

' Append the status text to the results window
.AppendText(s & EOL)

' Highlight failed tests in red
.SelectionColor = Color.Red

.Select(selectStart, s.Length)

.ClearUndo()

' Keep the most recent addition in view
.Select(.TextLength, 0)
.ScrollToCaret()

.ResumeLayout()
End With

End Sub
... Have you taken a look at the RichTextBox's RTF property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

Yes, I did look at the RTF property. I must admit that, despite your
reassurances, it looked like a lot of work. I know HTML well, but it did
not seem quite so straight forward on first inspection. It may still be
worth a punt though.

Charles


CMM said:
Good job testing out all of our flakey ideas. This was a very interesting
and
enlightening thread.

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties
to
set your formatting?
This is your bottleneck I take it as it will exponentially become slower
as
the text increases. Have you taken a look at the RichTextBox's RTF
property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

RTF codes aren't that difficult... it's a lot like HTML... check out this
link to get you started:
http://msdn.microsoft.com/library/d...tersInBoldInRichTextBoxControlVisualBasic.asp


Charles Law said:
Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I am
probably outputting too much information in the first instance. I know
that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I am
reminded of a similar situation put to me recently by a client. My answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed my
own
advice.

I'm going to cache the large amount of output generated by the worker
thread
and just output headings. If the user wishes to get more detail I will
load
it when requested, in one hit. Nice and quick. I will also allow the
entire
output to be saved, at which time I can generate the rtf. [I'm still
looking
for a neat in-memory rtf generator. Maybe the rich text box will do it
w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles


Cor Ligthert said:
Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of your
RTFBox go smooth without any waiting in a seperated thread. Collect the
information for that in another tier as well in a seperated thread. And
let the worker tiers get the information for the last in as well
seperated
threads.

This I can tell of course only now because we did not know that the
RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
C

Charles Law

Hi Jay

I am convinced that the RichTextBox is /a/ bottleneck.
The bottleneck may be the GC!

Interestingly, I noticed that in my tests, there was a noticeable pause
early in the updating of he RTB. It contained only a dozen lines, but I
detected a half-second pause as the screen was updating. This was
reproducible. There is every chance that this would re-occur later, and when
the RTB is fuller, the delay could be longer.
The bottleneck may actually be the way Charles' program is interacting
with memory.

In my real-world application this is true. But my samples are trivial.
Object creation is minimal, but it is true that in the event sample, an
EventArgs object is created every time an event is raised.
The bottleneck may be some unrelated program that happens to be running.

If this were true, I would expect it to affect both samples equally.
The bottleneck may be some unforeseen disk access, such as page swapping.

As above.
The bottleneck may be any number of other things...

I appreciate that you are illustrating the general point that the problem
might lie elsewhere, somewhere that we have not considered, but I have
attempted to make all things equal, so that the only differences in my
samples are down to the detail of the test that I am conducting.
Hence my suggestion to use CLR Profiler & other tools to try to accurately
identify where specifically the bottle neck is.

I have had another look at the CLR Profiler and I can only say that I
understand now why it is free. There are many diverse requirements for
memory profiling, but as far as I can see none of them are intuitively
handled by the CLR Profiler.
As Charles initially stated "The problem I have is that sometimes, for no
apparent reason, a step in my process takes an inordinate amount of time,
e.g 2.5 seconds instead of perhaps 300 ms." The "sometimes, for no
apparent reason" would suggest to me that it is not specifically the RTF
or the BeginInvoke, although it could be.

Agreed, But it may be that because of the way the RTB is implemented there
is a lot of memory manipulation going on that impairs performance.
In other words BeginInvoke & the RTF Box are both still suspects, however
the jury (CLR Profiler) has not convicted them of any crime.

Also agreed.

My gut feeling is that the RTB is not the best tool for the job that I
started out with. That said, the job I started out with is probably quite a
stretch full-stop. I suspect that I should take more control over the
delivery of status to the user based on the amount of information I am
trying to deliver. I am inclined to believe that the fundamental flaw is
that I am trying to present too much information in a short space of time,
with controls that are not designed for that kind of performance. I could
probably write a more efficient control, but there would be a lot of
functionality to reproduce, and it may not be necessary if I modify slightly
my contact with the user.

Charles
 
G

Guest

I did a quick test to get a feel for how fast the RichTextBox would be using
the Rtf property rather then the Text/Selection properties. It was still way
slooooww. I say ditch the RichTextBox control.


Charles Law said:
Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties
to
set your formatting?

The actual code is below (TestResults is the rich text box)

<code>
Private Sub UpdateStatus(ByVal s As String)

Dim selectStart As Integer

With TestResults
.SuspendLayout()

.Focus()

selectStart = .TextLength

' Append the status text to the results window
.AppendText(s & EOL)

' Highlight failed tests in red
.SelectionColor = Color.Red

.Select(selectStart, s.Length)

.ClearUndo()

' Keep the most recent addition in view
.Select(.TextLength, 0)
.ScrollToCaret()

.ResumeLayout()
End With

End Sub
... Have you taken a look at the RichTextBox's RTF property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

Yes, I did look at the RTF property. I must admit that, despite your
reassurances, it looked like a lot of work. I know HTML well, but it did
not seem quite so straight forward on first inspection. It may still be
worth a punt though.

Charles


CMM said:
Good job testing out all of our flakey ideas. This was a very interesting
and
enlightening thread.

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection properties
to
set your formatting?
This is your bottleneck I take it as it will exponentially become slower
as
the text increases. Have you taken a look at the RichTextBox's RTF
property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

RTF codes aren't that difficult... it's a lot like HTML... check out this
link to get you started:
http://msdn.microsoft.com/library/d...tersInBoldInRichTextBoxControlVisualBasic.asp


Charles Law said:
Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I am
probably outputting too much information in the first instance. I know
that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I am
reminded of a similar situation put to me recently by a client. My answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed my
own
advice.

I'm going to cache the large amount of output generated by the worker
thread
and just output headings. If the user wishes to get more detail I will
load
it when requested, in one hit. Nice and quick. I will also allow the
entire
output to be saved, at which time I can generate the rtf. [I'm still
looking
for a neat in-memory rtf generator. Maybe the rich text box will do it
w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles


Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of your
RTFBox go smooth without any waiting in a seperated thread. Collect the
information for that in another tier as well in a seperated thread. And
let the worker tiers get the information for the last in as well
seperated
threads.

This I can tell of course only now because we did not know that the
RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
C

Charles Law

Consider it ditched :)


CMM said:
I did a quick test to get a feel for how fast the RichTextBox would be
using
the Rtf property rather then the Text/Selection properties. It was still
way
slooooww. I say ditch the RichTextBox control.


Charles Law said:
Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection
properties
to
set your formatting?

The actual code is below (TestResults is the rich text box)

<code>
Private Sub UpdateStatus(ByVal s As String)

Dim selectStart As Integer

With TestResults
.SuspendLayout()

.Focus()

selectStart = .TextLength

' Append the status text to the results window
.AppendText(s & EOL)

' Highlight failed tests in red
.SelectionColor = Color.Red

.Select(selectStart, s.Length)

.ClearUndo()

' Keep the most recent addition in view
.Select(.TextLength, 0)
.ScrollToCaret()

.ResumeLayout()
End With

End Sub
... Have you taken a look at the RichTextBox's RTF property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF
codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

Yes, I did look at the RTF property. I must admit that, despite your
reassurances, it looked like a lot of work. I know HTML well, but it did
not seem quite so straight forward on first inspection. It may still be
worth a punt though.

Charles


CMM said:
Good job testing out all of our flakey ideas. This was a very
interesting
and
enlightening thread.

Just one more suggestion: You are updating the RichTextbox by doing
something like .Text = .Text + s and then using the Selection
properties
to
set your formatting?
This is your bottleneck I take it as it will exponentially become
slower
as
the text increases. Have you taken a look at the RichTextBox's RTF
property?
This lets you set the whole text with codes... and would allow you to
maintain your status messages in a StringBuilder complete with RTF
codes
that
you would just dump into the control in one swoop (Text=sb.ToString() )

RTF codes aren't that difficult... it's a lot like HTML... check out
this
link to get you started:
http://msdn.microsoft.com/library/d...tersInBoldInRichTextBoxControlVisualBasic.asp


:

Ok, yes. I see what you mean.

I think that one of the conclusions I should draw from this is that I
am
probably outputting too much information in the first instance. I know
that
sounds a bit like moving the goal posts, and that it doesn't solve the
underlying problem should I wish to output that amount of data, but I
am
reminded of a similar situation put to me recently by a client. My
answer
was to display less information and allow the user to drill down when
required, loading additional data as required. I think I should heed
my
own
advice.

I'm going to cache the large amount of output generated by the worker
thread
and just output headings. If the user wishes to get more detail I will
load
it when requested, in one hit. Nice and quick. I will also allow the
entire
output to be saved, at which time I can generate the rtf. [I'm still
looking
for a neat in-memory rtf generator. Maybe the rich text box will do it
w/o
making it visible]

Thanks to everyone for their ideas and feedback.

And thanks Cor.

Charles


Charles,

It has not to do with the way I told or others told

This has to do with the design.

When you use 3 instead of 2 tiers than you can let your loading of
your
RTFBox go smooth without any waiting in a seperated thread. Collect
the
information for that in another tier as well in a seperated thread.
And
let the worker tiers get the information for the last in as well
seperated
threads.

This I can tell of course only now because we did not know that the
RTFbox
was the bottleneck.

Describes this better what I mean?

Cor
 
C

Cor Ligthert

Jay,

My idea was only based what Charles was telling. I have no tools too show
that he could be wrong. Given that situation, I would make that redesign I
suggested..

:)

Cor
 
J

Jay B. Harlow [MVP - Outlook]

Charles,
My gut feeling is that the RTB is not the best tool for the job that I
started out with.
My gut feeling is the RTB is not the best tool for the job. However this is
from a presentation standpoint & not a performance standpoint!

It sounds like you are displaying when a series of events occurred in a
process, a ListView (in Details mode) or a Grid sounds like a better fit.
I am inclined to believe that the fundamental flaw is that I am trying to
present too much information in a short space of time, Agreed

with controls that are not designed for that kind of performance.
Depending on how short the "short space of time" is, there may not be a
control worthy of the performance...


Just a thought
Jay
 
C

Charles Law

Jay

I have been toying with trying a grid, now that I have moved away from the
RTB, but I fear that whilst the performance of the ListView is excellent, I
might sacrifice some of that performance by moving to a more complex
control.

The downside of abandoning the RTB is that I have lost the ability to save
the information with its colour highlighting. I have tried writing each
line, with colouring, to an invisible RTB at the end of the whole process so
that I can use its SaveFile method to save the RTF, but it takes minutes to
execute, so is not an option.

I could serialise the ListView to an xml file, with attributes to indicate
colour (or status, actually), and reload very quickly, but my user does not
have anything to display it other than my program. RTF seemed the best way
to include colouring so that it could be loaded by Word, for example, and
viewed and printed easily.

Isn't it always the way: one solves one problem often at the expense of
creating another.

Charles
 
J

Jay B. Harlow [MVP - Outlook]

Charles,
I'm concerned you are treating symptoms rather then treating the illness
itself. :-|

I would half expect DataGrid to be slower then ListView just by the very
nature of the controls.

It should not be that hard to create an RtfTextWriter class (ala
XmlTextWriter or HtmlTextWriter classes). That would encapsulate writing
formatted RTF to a text file (Stream). I would expect creating an
RtfTextReader would be more work...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top