472,333 Members | 1,053 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,333 software developers and data experts.

Time Critical Process in .NET

Hi guys

I have a time critical process, running on a worker thread. By "time
critical", I mean that certain parts of the process must be completed in a
specific time frame. The time when the process starts is not especially
important, but it must be complete within a small number of seconds.

The operations I am performing do not take a long time (hundreds of
milliseconds), but as each part of the process is complete, my worker thread
raises an event that is handled by the UI thread, to update a rich text
control with details of the completed operation. I am using a rich text box
so that when a failure occurs I can colour the message red.

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. When this happens, the complete process overruns my time
frame, and it has to be repeated. When I repeat the process there is every
chance that it completes in a realistic time, and all is well. If I stop
outputting to the screen, I do not get the problem.

When updating the screen on the UI thread, I use BeginInvoke, to marshal the
operation to the correct thread, and so as not to hold up the worker thread,
but this does not seem to help.

I realise that Windows (XP in this case) is not the ideal o/s for this type
of application, but does anyone have any ideas about how I could make my
application more deterministic? I am not certain what is going on in these
2.5 seconds, so it might be useful if I could find out, but I am not sure
how I would do that.

TIA

Charles
Nov 21 '05
80 3216
CMM,
To return execution to the caller of as quickly as possible. Huh?
If BeginInvoke
were truly asynchronous, Control.BeginInvoke is truly asynchronous! As is Delegate.BeginInvoke. Its
simply that they are implemented is different.
why should the caller have to wait around for the
method to do whatever work it has to do like prepare Because the delegate & parameters that are needed needs to be "copied" from
the worker thread to the UI thread. I hope you agree that even
Delegate.BeginInvoke needs to "copy" the delegate & parameters from the
worker thread to the thread pool thread. This "copying" can be called
marshalling . In both cases the delegate & parameters need to be marshaled
from one thread to the other.

NOTE: Unless you are crossing an app domain, the marshalling here only needs
to save a reference to the delegate & parameters to be sent so the other
thread can use them. When you cross an app domain the objects may need to be
serialized & deserialized on the other side...
and post a message via
the message pump

The message pump itself runs on the UI thread, it is the Application.Run
call that is either directly or indirectly called when you start your
application. I would expect Thread Pool threads to have something very
similar to a message pump, however rather being based on Win32 message
queues (PostMessage, GetMessage apis) that is uses a System.Collection.Queue
object.

Hope this helps
Jay
"CMM" <CM*@discussions.microsoft.com> wrote in message
news:99**********************************@microsof t.com...
Think very carefully about it. If the purpose of Control.BeginInvoke is
to
"execute on the thread that the control was created on", why would a
third
thread from the thread pool be involved?


To return execution to the caller of as quickly as possible. If
BeginInvoke
were truly asynchronous, why should the caller have to wait around for the
method to do whatever work it has to do like prepare and post a message
via
the message pump (or whatever it does to queue the control call) and then
finally return execution to the caller. Although... perhaps it is more
expensive to pick up a new thread for this purpose. IMO, picking up
threads
from the threadpool isn't as fast as it should be (sometimes taking a good
500ms or more). I'm not saying I'm correct about BeginInvoke... just
thinking
out loud about the possibilities. :-)

"Jay B. Harlow [MVP - Outlook]" wrote:
CMM,
> From the MSDN documentation for *Control.BeginInvoke*
> "Note The BeginInvoke method calls the specified delegate back on a
> different thread pool thread. You should not block a thread pool thread
> for
> any length of time."

IMHO that sounds like a serious documentation error! I will check with MS
to
make sure. I would expect the paragraph to read something like: "Note
The
BeginInvoke method calls the specified delegate back on the control's UI
thread. You should not block the control's UI thread for any length of
time."

The first paragraph is the important one. "Executes the specified
delegate
asynchronously on the thread that the control's underlying handle was
created on."

Think very carefully about it. If the purpose of Control.BeginInvoke is
to
"execute on the thread that the control was created on", why would a
third
thread from the thread pool be involved? Ergo the statement you quoted is
highly suspect and I will check with MS on it!
> I suspect what happens (indeed it seems to me that it HAS to happen
> this
> way) behind the scenes is that WorkerThread calls BeginInvoke,
> BeginInvoke
> spawns thread to queue the delegate call, Execution returns to
> WorkerThread,
> The New thread "queues" the call that will eventually occur on the UI
> thread.
> Makes sense to me. ;-)

Sounds like you are double queuing the request, which IMHO is one queuing
too many. In other words it makes more sense when the worker thread calls
BeginInvoke, BeginInvoke simply queues the request for the main thread to
execute it. Rather then have the worker thread, queue a request for the
thread pool, then the thread pool simply queues the request for the UI
thread.

I don't have the Rotor source loaded, however using ILDASM & Rotor,
Control.BeginInvoke calls Control.MarshaledInvoke, which registers a
private
windows message and calls the win32 GetWindowThreadProcessId &
PostMessage
APIs. I don't see any reference to the Thread Pool in the implementation
of
Control.BeginInvoke...

I will post something to MS about the documentation...

Hope this helps
Jay

"CMM" <CM*@discussions.microsoft.com> wrote in message
news:C2**********************************@microsof t.com...
>> Control.BeginInvoke does not "spawn a thread", it sounds like you are
>> thinking Delegate.BeginInvoke which needs to "spawn a thread"!
>
> From the MSDN documentation for *Control.BeginInvoke*
> "Note The BeginInvoke method calls the specified delegate back on a
> different thread pool thread. You should not block a thread pool thread
> for
> any length of time."
>
> I suspect what happens (indeed it seems to me that it HAS to happen
> this
> way) behind the scenes is that WorkerThread calls BeginInvoke,
> BeginInvoke
> spawns thread to queue the delegate call, Execution returns to
> WorkerThread,
> The New thread "queues" the call that will eventually occur on the UI
> thread.
> Makes sense to me. ;-)
>
> Having said that, I agree with your 80/20 characterization. It seems to
> me
> that the chances of his bottleneck being the event model is low
> compared
> to
> other possibilities.
>

<<snip>>

Nov 21 '05 #51
I can't remember where I got up to with this thread, so this is a general
update on the problem.

I ran the application again this morning, against the real equipment. The
time critical parts of the process now seem to be more stable, after
implementing some of the suggestions, but at the severe detriment to the UI.
As mentioned before, the background process raises events when it wants to
notify the UI that something has happened, and the event handler marshals
the event onto the UI thread, using a delegate and BeginInvoke, and appends
the message to a rich text box.

The problem is now that the screen appears to be updating at a reasonable
pace, but it is clearly lagging a long way behind the messages being
supplied to it. At its worst, the background process finished, and it took
over five minutes for the screen to catch up. FIVE MINUTES! I think I have
got my pattern wrong here. I don't mind the screen lagging slightly behind,
but five minutes is just silly.

Going back to basics, I want to (need to) capture the messages passed in all
the events that the background thread raises, and I want to maintain a
display of these messages. Some messages will be coloured red to make them
stand out to the user, which is why I have used a rich text box.

Is there a better pattern for this type of application?

Incidentally, I ran this on a 3.0 GHz P4 Dell laptop, not the slower
Celeron m/c, so it will be much worse on the intended target m/c.

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:uu***************@TK2MSFTNGP12.phx.gbl...
Hi guys

I have a time critical process, running on a worker thread. By "time
critical", I mean that certain parts of the process must be completed in a
specific time frame. The time when the process starts is not especially
important, but it must be complete within a small number of seconds.

The operations I am performing do not take a long time (hundreds of
milliseconds), but as each part of the process is complete, my worker
thread raises an event that is handled by the UI thread, to update a rich
text control with details of the completed operation. I am using a rich
text box so that when a failure occurs I can colour the message red.

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. When this happens, the complete process overruns my time
frame, and it has to be repeated. When I repeat the process there is every
chance that it completes in a realistic time, and all is well. If I stop
outputting to the screen, I do not get the problem.

When updating the screen on the UI thread, I use BeginInvoke, to marshal
the operation to the correct thread, and so as not to hold up the worker
thread, but this does not seem to help.

I realise that Windows (XP in this case) is not the ideal o/s for this
type of application, but does anyone have any ideas about how I could make
my application more deterministic? I am not certain what is going on in
these 2.5 seconds, so it might be useful if I could find out, but I am not
sure how I would do that.

TIA

Charles

Nov 21 '05 #52
Charles,
What was the extent of your changes? What exactly were your changes? Can you
apply an individual change at a time to isolate which one is causing the
problem.

Can you use CLR Profiler or another profiler to isolate *exactly* where the
slow down is? As other wise we are all just guessing as to where the problem
lies!

I saw a question the other day that I though might apply here. Is the slow
down occurring on the first Exception that occurs in your app? Remember for
apps that run under the debugger, the first exception usually takes about 2
seconds...

Is the JIT compiler loading & compiling code that causes the slow down?
want to maintain a display of these messages. Some messages will be
coloured red to make them stand out to the user, which is why I have used
a rich text box.
Have you considered an Owner Draw ListBox, a ListView or other control, that
is a little more "light weight" then a RichTextBox?

For example ListViewItem has a ForeColor property on it...

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...I can't remember where I got up to with this thread, so this is a general
update on the problem.

I ran the application again this morning, against the real equipment. The
time critical parts of the process now seem to be more stable, after
implementing some of the suggestions, but at the severe detriment to the
UI. As mentioned before, the background process raises events when it
wants to notify the UI that something has happened, and the event handler
marshals the event onto the UI thread, using a delegate and BeginInvoke,
and appends the message to a rich text box.

The problem is now that the screen appears to be updating at a reasonable
pace, but it is clearly lagging a long way behind the messages being
supplied to it. At its worst, the background process finished, and it took
over five minutes for the screen to catch up. FIVE MINUTES! I think I have
got my pattern wrong here. I don't mind the screen lagging slightly
behind, but five minutes is just silly.

Going back to basics, I want to (need to) capture the messages passed in
all the events that the background thread raises, and I want to maintain a
display of these messages. Some messages will be coloured red to make them
stand out to the user, which is why I have used a rich text box.

Is there a better pattern for this type of application?

Incidentally, I ran this on a 3.0 GHz P4 Dell laptop, not the slower
Celeron m/c, so it will be much worse on the intended target m/c.

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:uu***************@TK2MSFTNGP12.phx.gbl...
Hi guys

I have a time critical process, running on a worker thread. By "time
critical", I mean that certain parts of the process must be completed in
a specific time frame. The time when the process starts is not especially
important, but it must be complete within a small number of seconds.

The operations I am performing do not take a long time (hundreds of
milliseconds), but as each part of the process is complete, my worker
thread raises an event that is handled by the UI thread, to update a rich
text control with details of the completed operation. I am using a rich
text box so that when a failure occurs I can colour the message red.

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. When this happens, the complete process overruns my time
frame, and it has to be repeated. When I repeat the process there is
every chance that it completes in a realistic time, and all is well. If I
stop outputting to the screen, I do not get the problem.

When updating the screen on the UI thread, I use BeginInvoke, to marshal
the operation to the correct thread, and so as not to hold up the worker
thread, but this does not seem to help.

I realise that Windows (XP in this case) is not the ideal o/s for this
type of application, but does anyone have any ideas about how I could
make my application more deterministic? I am not certain what is going on
in these 2.5 seconds, so it might be useful if I could find out, but I am
not sure how I would do that.

TIA

Charles


Nov 21 '05 #53
Hi Jay

One of the changes I made was to stop exceptions being raised for events
that could occur as a normal part of the background process. I was throwing
an exception to indicate a process step failure, whereas I now always return
a Result class that indicates the state. That said, these failures did not
occur very often and, all being well, won't happen at all, but it is now
neater this way.

I also raised the priority of the worker thread to Highest.

I haven't got to grips with the CLR Profiler yet; perhaps I should :-)
Intuitively, I feel that the problem is that the worker thread is now taking
all the time it needs, and the UI thread is getting only a small amount of
time. If the worker thread is performing its tasks at full tilt it will
raise an event every 50 ms or so, with longer gaps here and there. I just
don't think that the UI can keep up. Messages appear on-screen at a goodly
rate, but as the rich text box gets fuller it appears to get slower. When
the whole process was over I saved the contents of the rich text box and
opened it in word. The file is 2 Mb long, and converts to 319 A4 pages.

As far as applying a change at a time, I am somewhat hampered by access to
equipment, and although I can test fairly well off-site, I don't get the
same problems because I can only execute a small number of the processes
properly.
Have you considered an Owner Draw ListBox, a ListView or other control,
that is a little more "light weight" then a RichTextBox?
I did think about this but thought that it would actually be slower. I
thought that as the rich text box is free text it should be quicker to tack
stuff on the end, whereas I imagine that the listview will create an object
for each line and would therefore take longer and be more memory hungry. Now
you suggest it though I think I will try it. In fact, if it is quicker it
will probably make the management and navigation of the information easier.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl... Charles,
What was the extent of your changes? What exactly were your changes? Can
you apply an individual change at a time to isolate which one is causing
the problem.

Can you use CLR Profiler or another profiler to isolate *exactly* where
the slow down is? As other wise we are all just guessing as to where the
problem lies!

I saw a question the other day that I though might apply here. Is the slow
down occurring on the first Exception that occurs in your app? Remember
for apps that run under the debugger, the first exception usually takes
about 2 seconds...

Is the JIT compiler loading & compiling code that causes the slow down?
want to maintain a display of these messages. Some messages will be
coloured red to make them stand out to the user, which is why I have used
a rich text box.


Have you considered an Owner Draw ListBox, a ListView or other control,
that is a little more "light weight" then a RichTextBox?

For example ListViewItem has a ForeColor property on it...

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
I can't remember where I got up to with this thread, so this is a general
update on the problem.

I ran the application again this morning, against the real equipment. The
time critical parts of the process now seem to be more stable, after
implementing some of the suggestions, but at the severe detriment to the
UI. As mentioned before, the background process raises events when it
wants to notify the UI that something has happened, and the event handler
marshals the event onto the UI thread, using a delegate and BeginInvoke,
and appends the message to a rich text box.

The problem is now that the screen appears to be updating at a reasonable
pace, but it is clearly lagging a long way behind the messages being
supplied to it. At its worst, the background process finished, and it
took over five minutes for the screen to catch up. FIVE MINUTES! I think
I have got my pattern wrong here. I don't mind the screen lagging
slightly behind, but five minutes is just silly.

Going back to basics, I want to (need to) capture the messages passed in
all the events that the background thread raises, and I want to maintain
a display of these messages. Some messages will be coloured red to make
them stand out to the user, which is why I have used a rich text box.

Is there a better pattern for this type of application?

Incidentally, I ran this on a 3.0 GHz P4 Dell laptop, not the slower
Celeron m/c, so it will be much worse on the intended target m/c.

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:uu***************@TK2MSFTNGP12.phx.gbl...
Hi guys

I have a time critical process, running on a worker thread. By "time
critical", I mean that certain parts of the process must be completed in
a specific time frame. The time when the process starts is not
especially important, but it must be complete within a small number of
seconds.

The operations I am performing do not take a long time (hundreds of
milliseconds), but as each part of the process is complete, my worker
thread raises an event that is handled by the UI thread, to update a
rich text control with details of the completed operation. I am using a
rich text box so that when a failure occurs I can colour the message
red.

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. When this happens, the complete process overruns my
time frame, and it has to be repeated. When I repeat the process there
is every chance that it completes in a realistic time, and all is well.
If I stop outputting to the screen, I do not get the problem.

When updating the screen on the UI thread, I use BeginInvoke, to marshal
the operation to the correct thread, and so as not to hold up the worker
thread, but this does not seem to help.

I realise that Windows (XP in this case) is not the ideal o/s for this
type of application, but does anyone have any ideas about how I could
make my application more deterministic? I am not certain what is going
on in these 2.5 seconds, so it might be useful if I could find out, but
I am not sure how I would do that.

TIA

Charles



Nov 21 '05 #54
Charles,

I still opt for the queue sample I gave you. Don't think about that as an
English queue.

In this case you put from every thread what is received as soon as possible.
Your mainthread is getting it out in the tempo he can process it.

I really think that this can make your processes more indipendent from
delays (although I agree that it never can solve that you cannot ring the
Big Ben 5 minutes over the hour).

There was as well an option for a stack in this thread, however the only
difference between a stack and a queue is that with a stack it goes last in
first out while the queue goes first in first out. (Still a little bit
English)

I think I wrote all the time queue well (it stays a terrible word)

:-)

Cor
Nov 21 '05 #55
Hi Cor

The reason I haven't tried the queue idea is that it seems to me to be, in
essence, what is happening when I use BeginInvoke.

With BeginInvoke, isn't it the case that the update gets queued until the UI
has time to put the message on the screen? In my scenario, the UI doesn't
get the time to do it very often, and when it does it is not quick enough.

Charles
"Cor Ligthert" <no************@planet.nl> wrote in message
news:ut**************@TK2MSFTNGP12.phx.gbl...
Charles,

I still opt for the queue sample I gave you. Don't think about that as an
English queue.

In this case you put from every thread what is received as soon as
possible. Your mainthread is getting it out in the tempo he can process
it.

I really think that this can make your processes more indipendent from
delays (although I agree that it never can solve that you cannot ring the
Big Ben 5 minutes over the hour).

There was as well an option for a stack in this thread, however the only
difference between a stack and a queue is that with a stack it goes last
in first out while the queue goes first in first out. (Still a little bit
English)

I think I wrote all the time queue well (it stays a terrible word)

:-)

Cor

Nov 21 '05 #56
Charles,

Are we talking about the same, a queue is a datastore in memory, that can be
feed from thread a,b,c,d,e,f, and read by thread y where it deletes every
time one from the bottom.

Therefore makes in my opinion a very smooth process possible. I have used
this forever long ago in past when that had other names. (It was nice to
make asynchronous database and datacom controllers, now named multi tier
applications).

Cor
Nov 21 '05 #57
I think we are talking about the same thing. My doubt is whether it will be
an improvement on using BeginInvoke.

Charles
"Cor Ligthert" <no************@planet.nl> wrote in message
news:uN**************@TK2MSFTNGP14.phx.gbl...
Charles,

Are we talking about the same, a queue is a datastore in memory, that can
be feed from thread a,b,c,d,e,f, and read by thread y where it deletes
every time one from the bottom.

Therefore makes in my opinion a very smooth process possible. I have used
this forever long ago in past when that had other names. (It was nice to
make asynchronous database and datacom controllers, now named multi tier
applications).

Cor

Nov 21 '05 #58
Charles,
As I mentioned before Control.BeginInvoke uses the Win32 PostMessage API.
(you can use ILDASM or Reflector to verify)

The Win32 PostMessage places messages in the Win32 Message Queue.
http://msdn.microsoft.com/library/de...ostmessage.asp
Rolling your own queuing verses BeginInvoke may or may not help. Before I
attempted rolling my own as Cor suggests. I would want to be certain that is
the aspect of the entire process that is hurting performance. The 80/20
rule!

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uo**************@TK2MSFTNGP14.phx.gbl...
Hi Cor

The reason I haven't tried the queue idea is that it seems to me to be, in
essence, what is happening when I use BeginInvoke.

With BeginInvoke, isn't it the case that the update gets queued until the
UI has time to put the message on the screen? In my scenario, the UI
doesn't get the time to do it very often, and when it does it is not quick
enough.

Charles
"Cor Ligthert" <no************@planet.nl> wrote in message
news:ut**************@TK2MSFTNGP12.phx.gbl...
Charles,

I still opt for the queue sample I gave you. Don't think about that as an
English queue.

In this case you put from every thread what is received as soon as
possible. Your mainthread is getting it out in the tempo he can process
it.

I really think that this can make your processes more indipendent from
delays (although I agree that it never can solve that you cannot ring the
Big Ben 5 minutes over the hour).

There was as well an option for a stack in this thread, however the only
difference between a stack and a queue is that with a stack it goes last
in first out while the queue goes first in first out. (Still a little bit
English)

I think I wrote all the time queue well (it stays a terrible word)

:-)

Cor


Nov 21 '05 #59
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Charles,
As I mentioned before Control.BeginInvoke uses the Win32 PostMessage API.
(you can use ILDASM or Reflector to verify)

The Win32 PostMessage places messages in the Win32 Message Queue.
http://msdn.microsoft.com/library/de...ostmessage.asp
Rolling your own queuing verses BeginInvoke may or may not help. Before I
attempted rolling my own as Cor suggests. I would want to be certain that
is the aspect of the entire process that is hurting performance. The 80/20
rule!

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uo**************@TK2MSFTNGP14.phx.gbl...
Hi Cor

The reason I haven't tried the queue idea is that it seems to me to be,
in essence, what is happening when I use BeginInvoke.

With BeginInvoke, isn't it the case that the update gets queued until the
UI has time to put the message on the screen? In my scenario, the UI
doesn't get the time to do it very often, and when it does it is not
quick enough.

Charles
"Cor Ligthert" <no************@planet.nl> wrote in message
news:ut**************@TK2MSFTNGP12.phx.gbl...
Charles,

I still opt for the queue sample I gave you. Don't think about that as
an English queue.

In this case you put from every thread what is received as soon as
possible. Your mainthread is getting it out in the tempo he can process
it.

I really think that this can make your processes more indipendent from
delays (although I agree that it never can solve that you cannot ring
the Big Ben 5 minutes over the hour).

There was as well an option for a stack in this thread, however the only
difference between a stack and a queue is that with a stack it goes last
in first out while the queue goes first in first out. (Still a little
bit English)

I think I wrote all the time queue well (it stays a terrible word)

:-)

Cor



Nov 21 '05 #60
CMM
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.
"Charles Law" wrote:
I can't remember where I got up to with this thread, so this is a general
update on the problem.

I ran the application again this morning, against the real equipment. The
time critical parts of the process now seem to be more stable, after
implementing some of the suggestions, but at the severe detriment to the UI.
As mentioned before, the background process raises events when it wants to
notify the UI that something has happened, and the event handler marshals
the event onto the UI thread, using a delegate and BeginInvoke, and appends
the message to a rich text box.

The problem is now that the screen appears to be updating at a reasonable
pace, but it is clearly lagging a long way behind the messages being
supplied to it. At its worst, the background process finished, and it took
over five minutes for the screen to catch up. FIVE MINUTES! I think I have
got my pattern wrong here. I don't mind the screen lagging slightly behind,
but five minutes is just silly.

Going back to basics, I want to (need to) capture the messages passed in all
the events that the background thread raises, and I want to maintain a
display of these messages. Some messages will be coloured red to make them
stand out to the user, which is why I have used a rich text box.

Is there a better pattern for this type of application?

Incidentally, I ran this on a 3.0 GHz P4 Dell laptop, not the slower
Celeron m/c, so it will be much worse on the intended target m/c.

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:uu***************@TK2MSFTNGP12.phx.gbl...
Hi guys

I have a time critical process, running on a worker thread. By "time
critical", I mean that certain parts of the process must be completed in a
specific time frame. The time when the process starts is not especially
important, but it must be complete within a small number of seconds.

The operations I am performing do not take a long time (hundreds of
milliseconds), but as each part of the process is complete, my worker
thread raises an event that is handled by the UI thread, to update a rich
text control with details of the completed operation. I am using a rich
text box so that when a failure occurs I can colour the message red.

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. When this happens, the complete process overruns my time
frame, and it has to be repeated. When I repeat the process there is every
chance that it completes in a realistic time, and all is well. If I stop
outputting to the screen, I do not get the problem.

When updating the screen on the UI thread, I use BeginInvoke, to marshal
the operation to the correct thread, and so as not to hold up the worker
thread, but this does not seem to help.

I realise that Windows (XP in this case) is not the ideal o/s for this
type of application, but does anyone have any ideas about how I could make
my application more deterministic? I am not certain what is going on in
these 2.5 seconds, so it might be useful if I could find out, but I am not
sure how I would do that.

TIA

Charles


Nov 21 '05 #61
CMM
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.

"Charles Law" wrote:
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Charles,
As I mentioned before Control.BeginInvoke uses the Win32 PostMessage API.
(you can use ILDASM or Reflector to verify)

The Win32 PostMessage places messages in the Win32 Message Queue.
http://msdn.microsoft.com/library/de...ostmessage.asp
Rolling your own queuing verses BeginInvoke may or may not help. Before I
attempted rolling my own as Cor suggests. I would want to be certain that
is the aspect of the entire process that is hurting performance. The 80/20
rule!

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uo**************@TK2MSFTNGP14.phx.gbl...
Hi Cor

The reason I haven't tried the queue idea is that it seems to me to be,
in essence, what is happening when I use BeginInvoke.

With BeginInvoke, isn't it the case that the update gets queued until the
UI has time to put the message on the screen? In my scenario, the UI
doesn't get the time to do it very often, and when it does it is not
quick enough.

Charles
"Cor Ligthert" <no************@planet.nl> wrote in message
news:ut**************@TK2MSFTNGP12.phx.gbl...
Charles,

I still opt for the queue sample I gave you. Don't think about that as
an English queue.

In this case you put from every thread what is received as soon as
possible. Your mainthread is getting it out in the tempo he can process
it.

I really think that this can make your processes more indipendent from
delays (although I agree that it never can solve that you cannot ring
the Big Ben 5 minutes over the hour).

There was as well an option for a stack in this thread, however the only
difference between a stack and a queue is that with a stack it goes last
in first out while the queue goes first in first out. (Still a little
bit English)

I think I wrote all the time queue well (it stays a terrible word)

:-)

Cor



Nov 21 '05 #62
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
"CMM" <CM*@discussions.microsoft.com> wrote in message
news:CB**********************************@microsof t.com...
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.
"Charles Law" wrote:
I can't remember where I got up to with this thread, so this is a general
update on the problem.

I ran the application again this morning, against the real equipment. The
time critical parts of the process now seem to be more stable, after
implementing some of the suggestions, but at the severe detriment to the
UI.
As mentioned before, the background process raises events when it wants
to
notify the UI that something has happened, and the event handler marshals
the event onto the UI thread, using a delegate and BeginInvoke, and
appends
the message to a rich text box.

The problem is now that the screen appears to be updating at a reasonable
pace, but it is clearly lagging a long way behind the messages being
supplied to it. At its worst, the background process finished, and it
took
over five minutes for the screen to catch up. FIVE MINUTES! I think I
have
got my pattern wrong here. I don't mind the screen lagging slightly
behind,
but five minutes is just silly.

Going back to basics, I want to (need to) capture the messages passed in
all
the events that the background thread raises, and I want to maintain a
display of these messages. Some messages will be coloured red to make
them
stand out to the user, which is why I have used a rich text box.

Is there a better pattern for this type of application?

Incidentally, I ran this on a 3.0 GHz P4 Dell laptop, not the slower
Celeron m/c, so it will be much worse on the intended target m/c.

Charles
"Charles Law" <bl***@nowhere.com> wrote in message
news:uu***************@TK2MSFTNGP12.phx.gbl...
> Hi guys
>
> I have a time critical process, running on a worker thread. By "time
> critical", I mean that certain parts of the process must be completed
> in a
> specific time frame. The time when the process starts is not especially
> important, but it must be complete within a small number of seconds.
>
> The operations I am performing do not take a long time (hundreds of
> milliseconds), but as each part of the process is complete, my worker
> thread raises an event that is handled by the UI thread, to update a
> rich
> text control with details of the completed operation. I am using a rich
> text box so that when a failure occurs I can colour the message red.
>
> 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. When this happens, the complete process overruns my
> time
> frame, and it has to be repeated. When I repeat the process there is
> every
> chance that it completes in a realistic time, and all is well. If I
> stop
> outputting to the screen, I do not get the problem.
>
> When updating the screen on the UI thread, I use BeginInvoke, to
> marshal
> the operation to the correct thread, and so as not to hold up the
> worker
> thread, but this does not seem to help.
>
> I realise that Windows (XP in this case) is not the ideal o/s for this
> type of application, but does anyone have any ideas about how I could
> make
> my application more deterministic? I am not certain what is going on in
> these 2.5 seconds, so it might be useful if I could find out, but I am
> not
> sure how I would do that.
>
> TIA
>
> Charles
>
>


Nov 21 '05 #63
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

Nov 21 '05 #64
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
"Cor Ligthert" <no************@planet.nl> wrote in message
news:um*************@tk2msftngp13.phx.gbl... 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

Nov 21 '05 #65
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
Nov 21 '05 #66
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" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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

Nov 21 '05 #67
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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl... 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

Nov 21 '05 #68
CMM
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/de...isualBasic.asp
"Charles Law" wrote:
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" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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


Nov 21 '05 #69
CMM
Correction: .Rtf = sb.ToString()

"CMM" wrote:
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/de...isualBasic.asp
"Charles Law" wrote:
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" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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


Nov 21 '05 #70
CMM
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.

"Jay B. Harlow [MVP - Outlook]" wrote:
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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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


Nov 21 '05 #71
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
</code>
... 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" <CM*@discussions.microsoft.com> wrote in message
news:CF**********************************@microsof t.com... 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/de...isualBasic.asp
"Charles Law" wrote:
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" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
> 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
>


Nov 21 '05 #72
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... 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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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


Nov 21 '05 #73
CMM
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" wrote:
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
</code>
... 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" <CM*@discussions.microsoft.com> wrote in message
news:CF**********************************@microsof t.com...
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/de...isualBasic.asp
"Charles Law" wrote:
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" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
> 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
>


Nov 21 '05 #74
Consider it ditched :-)
"CMM" <CM*@discussions.microsoft.com> wrote in message
news:8E**********************************@microsof t.com...
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" wrote:
> 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
</code>
> ... 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" <CM*@discussions.microsoft.com> wrote in message
news:CF**********************************@microsof t.com...
> 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/de...isualBasic.asp
>
>
> "Charles Law" wrote:
>
>> 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" <no************@planet.nl> wrote in message
>> news:en**************@TK2MSFTNGP14.phx.gbl...
>> > 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
>> >
>>
>>
>>


Nov 21 '05 #75
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
Nov 21 '05 #76
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

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... 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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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



Nov 21 '05 #77
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Oc*************@TK2MSFTNGP15.phx.gbl...
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

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
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



Nov 21 '05 #78
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

"Charles Law" <bl***@nowhere.com> wrote in message
news:ud**************@TK2MSFTNGP15.phx.gbl...
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Oc*************@TK2MSFTNGP15.phx.gbl...
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

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message news:%2****************@TK2MSFTNGP09.phx.gbl...
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

"Cor Ligthert" <no************@planet.nl> wrote in message
news:en**************@TK2MSFTNGP14.phx.gbl...
> 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
>



Nov 21 '05 #79

Jay
I'm concerned you are treating symptoms rather then treating the illness
itself. :-|
I wasn't aware that I was. Surely the illness is displaying too much data,
which I am addressing. I was just bemoaning the fact that the original
solution had its benefits, so now I have to regain those benefits by some
other means.
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...
I don't actually want to go down this route. I fancy someone somewhere must
have done this already. I just need to find it! You have prompted me to try
html though. That could be quicker and, as I know html, easier too. It
doesn't have to be rtf. The main requirement is that however I save the
data, it can be displayed outside my app, but retaining the colour coding.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP15.phx.gbl... 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

"Charles Law" <bl***@nowhere.com> wrote in message
news:ud**************@TK2MSFTNGP15.phx.gbl...
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Oc*************@TK2MSFTNGP15.phx.gbl...
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

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message news:%2****************@TK2MSFTNGP09.phx.gbl...
> 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
>
> "Cor Ligthert" <no************@planet.nl> wrote in message
> news:en**************@TK2MSFTNGP14.phx.gbl...
>> 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
>>
>
>



Nov 21 '05 #80
Charles,
I'm concerned you are treating symptoms rather then treating the illness
itself. :-|
I wasn't aware that I was. Surely the illness is displaying too much data,


I thought the illness was that your task takes too long:

<quote>
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.
</quote>

Of course the fact your task takes too long may be a symptom of a different
problem... such as the alleged display problem.

I have not seen anything that definitely suggests to me the problem is the
display itself. Although I will admit it is one of my prime candidates ;-)

Quirky little chicken & egg problem isn't it ;-)

Just a thought
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:O$**************@TK2MSFTNGP09.phx.gbl...
Jay
I'm concerned you are treating symptoms rather then treating the illness
itself. :-|


I wasn't aware that I was. Surely the illness is displaying too much data,
which I am addressing. I was just bemoaning the fact that the original
solution had its benefits, so now I have to regain those benefits by some
other means.
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...


I don't actually want to go down this route. I fancy someone somewhere
must have done this already. I just need to find it! You have prompted me
to try html though. That could be quicker and, as I know html, easier too.
It doesn't have to be rtf. The main requirement is that however I save the
data, it can be displayed outside my app, but retaining the colour coding.

Charles

<<snip>>
Nov 21 '05 #81

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

77
by: Charles Law | last post by:
Hi guys I have a time critical process, running on a worker thread. By "time critical", I mean that certain parts of the process must be...
0
by: concettolabs | last post by:
In today's business world, businesses are increasingly turning to PowerApps to develop custom business applications. PowerApps is a powerful tool...
0
better678
by: better678 | last post by:
Question: Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct? Answer: Java is an object-oriented...
0
by: CD Tom | last post by:
This happens in runtime 2013 and 2016. When a report is run and then closed a toolbar shows up and the only way to get it to go away is to right...
0
by: CD Tom | last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.