Time Critical Process in .NET

  • Thread starter Thread starter Charles Law
  • Start date Start date
If the culprit is the events perhaps you should rethink your design... and
use a shared or global variable to communicate state. The UI thread would
periodically check the status rather then the worker thread informing the UI
via events.

Charles Law said:
It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds. Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I can
discern. Therefore, the entire sequence takes longer than the allowed time,
and the process fails. That said, it is not always task 1 that takes the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I have
timed the serial comms carefully, and it consistently takes no more than 25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that the
task is starting. The UI updates a rich text control using BeginInvoke. I am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen appears to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Niki Estner said:
Charles Law said:
Hi Niki

Thanks for the response. I currently display the absolute and elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more time
displays, but it would generate a lot of output, and whilst it might tell
me when and where in my code the excess time is taken, I am not sure it
will necessarily tell me why. I don't think it is my code (they all say
that), because it is so random.

Is it really random? How can you know without knowing where it happens? I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there a
normal distribution around 300 ms plus some peaks at 2,5 s? If so, did you
check where those peaks are? (I always dump output like that to a text
file and use Excel to analyze it later)
- Monitor the .NET performance counters. Is there maybe some correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name of the
performance counter, should be something like "Number of GCs" in the ".NET
Memory" performance counters section. It increases by one with each GC
collection. Use perfmon to record it while you test your app.
- Which GC do you use?

How many are there? I thought there was just the one, built-in to the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation (mscorwks.dll) and
Server (mscorsvr.dll). When running in Workstation mode, latency is more
of a concern than space or efficiency. A server with multiple processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I think the
workstation version is the better choice for you anyway.

Niki
 
The status is accumulated in the rich text box, so just checking it
periodically would mean that some state changes could be missed. The rich
text box needs to keep a history of all states, as notified by the worker
thread.

One thought I had was to accumulate the state in-memory, which would
undoubtedly be quicker than updating the screen all the time. The problem I
can see with that is that I don't have an in-memory class that can interpret
rtf codes, such as the ones that are embedded in the rich text control to
show failed processes in red.

Do you know of a class that can process/manipulate rtf w/o rendering it?

Charles


CMM said:
If the culprit is the events perhaps you should rethink your design... and
use a shared or global variable to communicate state. The UI thread would
periodically check the status rather then the worker thread informing the
UI
via events.

Charles Law said:
It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I have
timed the serial comms carefully, and it consistently takes no more than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that the
task is starting. The UI updates a rich text control using BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Niki Estner said:
Hi Niki

Thanks for the response. I currently display the absolute and elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more time
displays, but it would generate a lot of output, and whilst it might
tell
me when and where in my code the excess time is taken, I am not sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there a
normal distribution around 300 ms plus some peaks at 2,5 s? If so, did
you
check where those peaks are? (I always dump output like that to a text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation (mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I think
the
workstation version is the better choice for you anyway.

Niki
 
There are certainly points in my process where I could perform a garbage
collect w/o upsetting the timing, so I will try a gc.Collect there and see
what happens.

Charles
 
Charles,

Did you ever saw that queue sample (using multithreading) that I once have
sent to this newsgroup. Maybe can that be a solution because it can maybe
make your problem easier to handle. This is because I have the idea that I
read some things in your messages in this thread what can be solved with
this.

http://groups-beta.google.com/group/microsoft.public.dotnet.languages.vb/msg/55629fad6b6eb48a

This is real "a sample without any production value", in the thread is as
well another sample with a more realistic approach.

Cor
 
Charles,

I did not look all solutions you got, however for me looks some as putting
the horse behind the car.

By instance that looking for the garbage collecting or screensaver (in my
opinion wild guesses) will cost time, and that will in my opinion only make
your problem worse. I can add a virusscanner, from which I have seen, can
have a terrible influence on a laptop, and there are a lot of those.

In my opinion do you have to fix the problem inside your solution and not
outside, that never will lead to results. It can happen again, when a kind
of change in the system configuration is happening, that you did not expect.

Just my thought,

Cor
 
Hi Cor

I have just looked at it now. I will have a think about how it could help
me.

Thanks.

Charles
 
Cor

I agree with you that I need to fix the problem within my programme.
However, as you say, things like virus checkers can have an adverse effect
on performance, so I will also have to specify that virus checking must be
disabled. This laptop lives in a secure lab environment, and will only ever
be used for this process, so it is not unreasonable to expect that it will
never be the subject of a virus attack.

Charles
 
The worker thread can push "states" into a stack collection. The UI thread
can pop states out. You'd use the SyncLock mechanism (VB parlance) to allow
for both threads to access the collection. The UI thread would NOT enumerate
the collection and fill the rich text box at the same time (which might be an
expensive process)... that's dumb... rather it would pop out the states and
collect them itself and then fill the textbox on its own time so as to leave
the stack collection alone as quickly as possible.

Your RTF thing confused me... is the worker thread sending back RTF strings?
Why? And if so, why can't you just store those same strings in a regular ol'
collection?

Just an idea.

Charles Law said:
The status is accumulated in the rich text box, so just checking it
periodically would mean that some state changes could be missed. The rich
text box needs to keep a history of all states, as notified by the worker
thread.

One thought I had was to accumulate the state in-memory, which would
undoubtedly be quicker than updating the screen all the time. The problem I
can see with that is that I don't have an in-memory class that can interpret
rtf codes, such as the ones that are embedded in the rich text control to
show failed processes in red.

Do you know of a class that can process/manipulate rtf w/o rendering it?

Charles


CMM said:
If the culprit is the events perhaps you should rethink your design... and
use a shared or global variable to communicate state. The UI thread would
periodically check the status rather then the worker thread informing the
UI
via events.

Charles Law said:
It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I have
timed the serial comms carefully, and it consistently takes no more than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that the
task is starting. The UI updates a rich text control using BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more time
displays, but it would generate a lot of output, and whilst it might
tell
me when and where in my code the excess time is taken, I am not sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there a
normal distribution around 300 ms plus some peaks at 2,5 s? If so, did
you
check where those peaks are? (I always dump output like that to a text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation (mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I think
the
workstation version is the better choice for you anyway.

Niki
 
CMM,
Causing the UI thread to periodically check the status means that it would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are using...

Using BeginInvoke means the UI thread will only update the status when the
critical thread made a change...

Just a thought
Jay

CMM said:
If the culprit is the events perhaps you should rethink your design... and
use a shared or global variable to communicate state. The UI thread would
periodically check the status rather then the worker thread informing the
UI
via events.

Charles Law said:
It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I have
timed the serial comms carefully, and it consistently takes no more than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that the
task is starting. The UI updates a rich text control using BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Niki Estner said:
Hi Niki

Thanks for the response. I currently display the absolute and elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more time
displays, but it would generate a lot of output, and whilst it might
tell
me when and where in my code the excess time is taken, I am not sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there a
normal distribution around 300 ms plus some peaks at 2,5 s? If so, did
you
check where those peaks are? (I always dump output like that to a text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation (mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I think
the
workstation version is the better choice for you anyway.

Niki
 
Charles,
Once you rule out other apps (NAV, Screen Savers), which you cannot really
do anything real about anyway (process priority may help, a little). CMM &
my suggestions of redesigning the critical part is what you will need to do.

If you decide to use GC.Collect be certain to read & adhere to Rule #1 at:

http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx
http://blogs.msdn.com/ricom/archive/2003/12/02/40780.aspx


The following links may (or may not) help in the redesign:
http://blogs.msdn.com/ricom/

http://blogs.msdn.com/maoni/

(the above two blogs have a number of useful articles, check all the
articles).

http://msdn.microsoft.com/library/d...y/en-us/dndotnet/html/highperfmanagedapps.asp


http://blogs.msdn.com/junfeng/archive/2004/07/13/181534.aspx

I would consider recoding the critical thread in C++ if profiling proved
that the GC & managed code was the problem...

What parameters are on your events? I normally use EventArgs.Empty instead
of New EventArgs. If you have a custom EventArgs class, I would consider
making it read write & reusing a single instance for all events that may be
raised by the critical code. Assuming that the GC is the problem...

I thought CLR Profiling will identify if your critical code itself is taking
all the time or if another thread is getting all the time. In other words
when you critical thread takes 2.5 seconds, how much of that CPU time did
your critical thread get & how much did other threads get...

Hope this helps
Jay
 
You're probably right. But, I would think that a simple thread Timer (rather
than a loop) in the UI is efficient enough to not steal CPU time from the
worker thread... and it might (or not) be more efficient than the event model
/ begininvoke he is using.

Jay B. Harlow said:
CMM,
Causing the UI thread to periodically check the status means that it would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are using...

Using BeginInvoke means the UI thread will only update the status when the
critical thread made a change...

Just a thought
Jay

CMM said:
If the culprit is the events perhaps you should rethink your design... and
use a shared or global variable to communicate state. The UI thread would
periodically check the status rather then the worker thread informing the
UI
via events.

Charles Law said:
It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I have
timed the serial comms carefully, and it consistently takes no more than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that the
task is starting. The UI updates a rich text control using BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more time
displays, but it would generate a lot of output, and whilst it might
tell
me when and where in my code the excess time is taken, I am not sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there a
normal distribution around 300 ms plus some peaks at 2,5 s? If so, did
you
check where those peaks are? (I always dump output like that to a text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation (mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I think
the
workstation version is the better choice for you anyway.

Niki
 
CMM,
What do you mean by "thread Timer"? Remember there are three timers in .NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code when it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


CMM said:
You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from the
worker thread... and it might (or not) be more efficient than the event
model
/ begininvoke he is using.

Jay B. Harlow said:
CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status when
the
critical thread made a change...

Just a thought
Jay

CMM said:
If the culprit is the events perhaps you should rethink your design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I
can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name
of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
I'd use the forms timer component as it's the best suited for this purpose...
he's after all updating a form :-) ... set to some reasonable interval that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's doing-
is not without expense. A third thread has to be picked up from the pool or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might prove
detrimental to his worker thread. There's no guarantee that the work done by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and then
whoever is interested in your status can look it up.


Jay B. Harlow said:
CMM,
What do you mean by "thread Timer"? Remember there are three timers in .NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code when it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


CMM said:
You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from the
worker thread... and it might (or not) be more efficient than the event
model
/ begininvoke he is using.

Jay B. Harlow said:
CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I
can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name
of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
To clarify.... After thinking about it I realize that the timer model might
have the same problems as the BeginInvoke model. However, it might still
alleviate the worker thread somewhat. Like I said... and AFAIK... when
BeginInvoke is called the framework has to spawn a thread momentarily in
order to return execution to the caller "immediately" before marshalling the
call to the UI thread. This means that execution is not really really
returned to the caller "immediately." Why should the worker thread incur this
expense? Let the UI thread deal with it (via the Timer).

Alas, in the end... I strongly suspect that your advice to use
EventArgs.Empty or *reuse* a custom eventargs object (with settable
properties) rather than reinstantiating a new one would (coupled with well
placed gc.Collects) help his problem more than any changes to his
Event/BeginInvoke technique.


CMM said:
I'd use the forms timer component as it's the best suited for this purpose...
he's after all updating a form :-) ... set to some reasonable interval that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's doing-
is not without expense. A third thread has to be picked up from the pool or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might prove
detrimental to his worker thread. There's no guarantee that the work done by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and then
whoever is interested in your status can look it up.


Jay B. Harlow said:
CMM,
What do you mean by "thread Timer"? Remember there are three timers in .NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code when it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


CMM said:
You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from the
worker thread... and it might (or not) be more efficient than the event
model
/ begininvoke he is using.

:

CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I
can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name
of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
CMM,
when
BeginInvoke is called the framework has to spawn a thread momentarily in
order to return execution to the caller "immediately"
Control.BeginInvoke does not "spawn a thread", it sounds like you are
thinking Delegate.BeginInvoke which needs to "spawn a thread"!

As long as you are not crossing an AppDomain my understanding is that no
real "marshalling" takes place either.

I would however expect the parameters to BeginInvoke to be "packaged" in an
"invoke" queue. This "invoke" queue could be the Win32 message queue, or it
could be a delegate & a parameters queue. This packaging in an invoke queue,
might not be any longer then your putting the information on a stack...

I would favor events due to the 80/20 rule, and I would use profiling to
identify if BeginInvoke was truly the bottleneck...

Remember that most programs follow the 80/20 rule (link below) that is 80%
of the execution time of your program is spent in 20% of your code. I will
optimize the 20% once that 20% has been identified & proven to be a
performance problem via profiling (see CLR Profiler in my other message).

For info on the 80/20 rule & optimizing only the 20% see Martin Fowler's
article "Yet Another Optimization Article" at
http://martinfowler.com/ieeeSoftware/yetOptimization.pdf

Hope this helps
Jay

CMM said:
To clarify.... After thinking about it I realize that the timer model
might
have the same problems as the BeginInvoke model. However, it might still
alleviate the worker thread somewhat. Like I said... and AFAIK... when
BeginInvoke is called the framework has to spawn a thread momentarily in
order to return execution to the caller "immediately" before marshalling
the
call to the UI thread. This means that execution is not really really
returned to the caller "immediately." Why should the worker thread incur
this
expense? Let the UI thread deal with it (via the Timer).

Alas, in the end... I strongly suspect that your advice to use
EventArgs.Empty or *reuse* a custom eventargs object (with settable
properties) rather than reinstantiating a new one would (coupled with well
placed gc.Collects) help his problem more than any changes to his
Event/BeginInvoke technique.


CMM said:
I'd use the forms timer component as it's the best suited for this
purpose...
he's after all updating a form :-) ... set to some reasonable interval
that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's
doing-
is not without expense. A third thread has to be picked up from the pool
or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might
prove
detrimental to his worker thread. There's no guarantee that the work done
by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to
me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and
then
whoever is interested in your status can look it up.


Jay B. Harlow said:
CMM,
What do you mean by "thread Timer"? Remember there are three timers in
.NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the
third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code
when it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from
the
worker thread... and it might (or not) be more efficient than the
event
model
/ begininvoke he is using.

:

CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would
think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status
when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your
design...
and
use a shared or global variable to communicate state. The UI
thread
would
periodically check the status rather then the worker thread
informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the
same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms,
say.

The expectation, therefore, is that the whole process is over in
less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no
reason I
can
discern. Therefore, the entire sequence takes longer than the
allowed
time,
and the process fails. That said, it is not always task 1 that
takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port.
I
have
timed the serial comms carefully, and it consistently takes no
more
than
25
ms to send and receive data. Thus, I conclude that the time is
spent
elsewhere.

Before each task is started, an event is raised to inform the UI
that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for
example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result
from
the
clearing of a backlog.

When the UI displays the task being performed, I display the
absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the
difference
between the expected and actual timings. I guess I could add
more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am
not
sure
it
will necessarily tell me why. I don't think it is my code
(they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is
there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If
so,
did
you
check where those peaks are? (I always dump output like that to
a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact
name
of
the
performance counter, should be something like "Number of GCs"
in the
".NET
Memory" performance counters section. It increases by one with
each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in
to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode,
latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency,
but
throughput is now a top priority. Rather than shoehorn both of
these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but
I
think
the
workstation version is the better choice for you anyway.

Niki
 
CMM,
Its seems that we are discussing the benefits of Polling over the benefits
on Events. In my experience Events are almost always better then polling!
Hence my comments... Yes polling may be better here, however I would use the
80

The "don't call us, we'll call you" pattern if you will. :-)

The fact that one object exists "in" a critical thread, while the second
object exists "in" the UI is largely immaterial. I would have the object
that exists in the critical object, simply raise one or more events to
notify others that something significant occured, then continually "pester"
it to see if it changed... Other objects such as the Form would handle these
events. In the case of worker thread & UI thread, a Form/Control on the UI
thread itself would use IsInvokeRequired to decide if the BeginInvoked
needed to be called or not.

Now because the "BeginInvoke" is encapsulated in the Form itself, if
profiling demonstrated that it was the bottle neck, then I can simply change
the form to use a Timer or other method to allow the critical thread to
notify the UI thread of changes...


In VS.NET 2005 (.NET 2.0 aka Whidbey, due out later in 2005) there is the
BackgroundWorker class that will simplify allowing a worker thread (object)
notify the UI thread (object) about "significant" events (progress changed &
completed). Basically a Mediator between the UI object/thread and the worker
object/thread...

http://msdn2.microsoft.com/library/4852et58.aspx

So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.
??

I am referring to Control.BeginInvoke not Delegate.BeginInvoke, no threads
are created/taken & released from the thread pool!

Hope this helps
Jay



CMM said:
I'd use the forms timer component as it's the best suited for this
purpose...
he's after all updating a form :-) ... set to some reasonable interval
that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's
doing-
is not without expense. A third thread has to be picked up from the pool
or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might
prove
detrimental to his worker thread. There's no guarantee that the work done
by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to
me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and then
whoever is interested in your status can look it up.


Jay B. Harlow said:
CMM,
What do you mean by "thread Timer"? Remember there are three timers in
.NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the
third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code when
it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


CMM said:
You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from
the
worker thread... and it might (or not) be more efficient than the event
model
/ begininvoke he is using.

:

CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your
design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread
informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the
same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms,
say.

The expectation, therefore, is that the whole process is over in
less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason
I
can
discern. Therefore, the entire sequence takes longer than the
allowed
time,
and the process fails. That said, it is not always task 1 that
takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is
spent
elsewhere.

Before each task is started, an event is raised to inform the UI
that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example,
and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result
from
the
clearing of a backlog.

When the UI displays the task being performed, I display the
absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the
difference
between the expected and actual timings. I guess I could add
more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they
all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is
there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If
so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact
name
of
the
performance counter, should be something like "Number of GCs" in
the
".NET
Memory" performance counters section. It increases by one with
each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in
to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency
is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of
these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
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.

Jay B. Harlow said:
CMM,
when
BeginInvoke is called the framework has to spawn a thread momentarily in
order to return execution to the caller "immediately"
Control.BeginInvoke does not "spawn a thread", it sounds like you are
thinking Delegate.BeginInvoke which needs to "spawn a thread"!

As long as you are not crossing an AppDomain my understanding is that no
real "marshalling" takes place either.

I would however expect the parameters to BeginInvoke to be "packaged" in an
"invoke" queue. This "invoke" queue could be the Win32 message queue, or it
could be a delegate & a parameters queue. This packaging in an invoke queue,
might not be any longer then your putting the information on a stack...

I would favor events due to the 80/20 rule, and I would use profiling to
identify if BeginInvoke was truly the bottleneck...

Remember that most programs follow the 80/20 rule (link below) that is 80%
of the execution time of your program is spent in 20% of your code. I will
optimize the 20% once that 20% has been identified & proven to be a
performance problem via profiling (see CLR Profiler in my other message).

For info on the 80/20 rule & optimizing only the 20% see Martin Fowler's
article "Yet Another Optimization Article" at
http://martinfowler.com/ieeeSoftware/yetOptimization.pdf

Hope this helps
Jay

CMM said:
To clarify.... After thinking about it I realize that the timer model
might
have the same problems as the BeginInvoke model. However, it might still
alleviate the worker thread somewhat. Like I said... and AFAIK... when
BeginInvoke is called the framework has to spawn a thread momentarily in
order to return execution to the caller "immediately" before marshalling
the
call to the UI thread. This means that execution is not really really
returned to the caller "immediately." Why should the worker thread incur
this
expense? Let the UI thread deal with it (via the Timer).

Alas, in the end... I strongly suspect that your advice to use
EventArgs.Empty or *reuse* a custom eventargs object (with settable
properties) rather than reinstantiating a new one would (coupled with well
placed gc.Collects) help his problem more than any changes to his
Event/BeginInvoke technique.


CMM said:
I'd use the forms timer component as it's the best suited for this
purpose...
he's after all updating a form :-) ... set to some reasonable interval
that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's
doing-
is not without expense. A third thread has to be picked up from the pool
or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might
prove
detrimental to his worker thread. There's no guarantee that the work done
by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to
me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and
then
whoever is interested in your status can look it up.


:

CMM,
What do you mean by "thread Timer"? Remember there are three timers in
.NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the
third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code
when it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from
the
worker thread... and it might (or not) be more efficient than the
event
model
/ begininvoke he is using.

:

CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would
think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status
when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your
design...
and
use a shared or global variable to communicate state. The UI
thread
would
periodically check the status rather then the worker thread
informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the
same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms,
say.

The expectation, therefore, is that the whole process is over in
less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no
reason I
can
discern. Therefore, the entire sequence takes longer than the
allowed
time,
and the process fails. That said, it is not always task 1 that
takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port.
I
have
timed the serial comms carefully, and it consistently takes no
more
than
25
ms to send and receive data. Thus, I conclude that the time is
spent
elsewhere.

Before each task is started, an event is raised to inform the UI
that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for
example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result
from
the
clearing of a backlog.

When the UI displays the task being performed, I display the
absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the
difference
between the expected and actual timings. I guess I could add
more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am
not
sure
it
will necessarily tell me why. I don't think it is my code
(they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is
there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If
so,
did
you
check where those peaks are? (I always dump output like that to
a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact
name
of
the
performance counter, should be something like "Number of GCs"
in the
".NET
Memory" performance counters section. It increases by one with
each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in
to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode,
latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency,
but
throughput is now a top priority. Rather than shoehorn both of
these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but
I
think
the
workstation version is the better choice for you anyway.

Niki
 
I tend to agree with all your comments...

But, now I'm all curious to find out if indeed Control.BeginInvoke doesn't
(momentarily) make use of a thread pool thread to queue up the delegate call.
I'm not saying that the call is carried out in the thread pool thread, only
that the actuall "queueing up" happens there. Could be that I was under the
wrong impression. Time to go churn out some play code... for edification! :-)

Regards.

Jay B. Harlow said:
CMM,
Its seems that we are discussing the benefits of Polling over the benefits
on Events. In my experience Events are almost always better then polling!
Hence my comments... Yes polling may be better here, however I would use the
80

The "don't call us, we'll call you" pattern if you will. :-)

The fact that one object exists "in" a critical thread, while the second
object exists "in" the UI is largely immaterial. I would have the object
that exists in the critical object, simply raise one or more events to
notify others that something significant occured, then continually "pester"
it to see if it changed... Other objects such as the Form would handle these
events. In the case of worker thread & UI thread, a Form/Control on the UI
thread itself would use IsInvokeRequired to decide if the BeginInvoked
needed to be called or not.

Now because the "BeginInvoke" is encapsulated in the Form itself, if
profiling demonstrated that it was the bottle neck, then I can simply change
the form to use a Timer or other method to allow the critical thread to
notify the UI thread of changes...


In VS.NET 2005 (.NET 2.0 aka Whidbey, due out later in 2005) there is the
BackgroundWorker class that will simplify allowing a worker thread (object)
notify the UI thread (object) about "significant" events (progress changed &
completed). Basically a Mediator between the UI object/thread and the worker
object/thread...

http://msdn2.microsoft.com/library/4852et58.aspx

So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.
??

I am referring to Control.BeginInvoke not Delegate.BeginInvoke, no threads
are created/taken & released from the thread pool!

Hope this helps
Jay



CMM said:
I'd use the forms timer component as it's the best suited for this
purpose...
he's after all updating a form :-) ... set to some reasonable interval
that
makes sense in the context of a human looking at a screen.

BeginInvoke- especially calling it in such *quick succession* as he's
doing-
is not without expense. A third thread has to be picked up from the pool
or
created before the call is marshalled to the UI thread. Normally, nobody
cares and there's no noticeable performance impact.... but this might
prove
detrimental to his worker thread. There's no guarantee that the work done
by
the delegate called via the previous BeginInvoke is finished before
BeginInvoke is called again. So, the calls "build up", threads are
created/taken and then released from the pool, all in a blink of an eye.

That can't be good for his worker thread. I don't know. It just seems to
me
that a "time critical" thread shouldn't have to worry in any way about
notifying other threads of status. Fill a stack, forget about it, and then
whoever is interested in your status can look it up.


Jay B. Harlow said:
CMM,
What do you mean by "thread Timer"? Remember there are three timers in
.NET.

- System.Threading.Timer
- System.Timers.Timer
- System.Windows.Forms.Timer

The first two you will need to use BeginInvoke either directly or
indirectly, so I don't really see any potential "win" there. While the
third
will be on the UI thread.

My point is in all three cases the UI thread will be exectuting code when
it
could simply wait for the BeginInvoke from the critical thread...

Hope this helps
Jay


You're probably right. But, I would think that a simple thread Timer
(rather
than a loop) in the UI is efficient enough to not steal CPU time from
the
worker thread... and it might (or not) be more efficient than the event
model
/ begininvoke he is using.

:

CMM,
Causing the UI thread to periodically check the status means that it
would
need to use CPU time that the critical thread may need, I would think
Charles would want to minimize the amount of work other threads are
using...

Using BeginInvoke means the UI thread will only update the status when
the
critical thread made a change...

Just a thought
Jay

If the culprit is the events perhaps you should rethink your
design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread
informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the
same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms,
say.

The expectation, therefore, is that the whole process is over in
less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason
I
can
discern. Therefore, the entire sequence takes longer than the
allowed
time,
and the process fails. That said, it is not always task 1 that
takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is
spent
elsewhere.

Before each task is started, an event is raised to inform the UI
that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example,
and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result
from
the
clearing of a backlog.

When the UI displays the task being performed, I display the
absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the
difference
between the expected and actual timings. I guess I could add
more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they
all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is
there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If
so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact
name
of
the
performance counter, should be something like "Number of GCs" in
the
".NET
Memory" performance counters section. It increases by one with
each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in
to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency
is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of
these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
I see what you mean with the stack idea. It's a bit like the way BeginInvoke
would work though, in that the worker thread appends strings to the rich
text control, and the UI thread removes them, asynchronously, and puts them
on the screen. The difference being, perhaps, that I could have more control
over when it all happens.

As far as the rtf goes, there are actually several events raised. When all
is well a Feedback event is raised, and the string passed is placed in the
rich text control unchanged. When a failure occurs, a different event is
raised, and the UI handler that sinks this puts the string into the rich
text control with a fore colour of red.

Charles


CMM said:
The worker thread can push "states" into a stack collection. The UI thread
can pop states out. You'd use the SyncLock mechanism (VB parlance) to
allow
for both threads to access the collection. The UI thread would NOT
enumerate
the collection and fill the rich text box at the same time (which might be
an
expensive process)... that's dumb... rather it would pop out the states
and
collect them itself and then fill the textbox on its own time so as to
leave
the stack collection alone as quickly as possible.

Your RTF thing confused me... is the worker thread sending back RTF
strings?
Why? And if so, why can't you just store those same strings in a regular
ol'
collection?

Just an idea.

Charles Law said:
The status is accumulated in the rich text box, so just checking it
periodically would mean that some state changes could be missed. The rich
text box needs to keep a history of all states, as notified by the worker
thread.

One thought I had was to accumulate the state in-memory, which would
undoubtedly be quicker than updating the screen all the time. The problem
I
can see with that is that I don't have an in-memory class that can
interpret
rtf codes, such as the ones that are embedded in the rich text control to
show failed processes in red.

Do you know of a class that can process/manipulate rtf w/o rendering it?

Charles


CMM said:
If the culprit is the events perhaps you should rethink your design...
and
use a shared or global variable to communicate state. The UI thread
would
periodically check the status rather then the worker thread informing
the
UI
via events.

:

It's random in the sense that it doesn't always happen during the same
operation, and sometimes it doesn't happen at all.

The worker thread, repeatedly, does things like this:

DoTask1
DoTask2
DoTask7
DoTask2

All these tasks have to be performed within a couple of seconds.
Nominally,
task1 takes 60 ms, task 2 takes 10 ms, and task 7 takes 550 ms, say.

The expectation, therefore, is that the whole process is over in less
than 1
second. Sometimes, though, task 1 takes 2.5 seconds, for no reason I
can
discern. Therefore, the entire sequence takes longer than the allowed
time,
and the process fails. That said, it is not always task 1 that takes
the
excess time; it could be task 2, or task 7, or task 43.

Each of these tasks will send and receive data on a serial port. I
have
timed the serial comms carefully, and it consistently takes no more
than
25
ms to send and receive data. Thus, I conclude that the time is spent
elsewhere.

Before each task is started, an event is raised to inform the UI that
the
task is starting. The UI updates a rich text control using
BeginInvoke. I
am
wondering if these requests to update the UI pile up, for example, and
eventually get flushed, holding up the worker thread. The screen
appears
to
update steadily, but by definition the screen updates will not be
synchronised to the update requests, so some of them might result from
the
clearing of a backlog.

When the UI displays the task being performed, I display the absolute
time
and the delta based on a high res counter.

I will have a look at the performance counter you mention.

Charles


Hi Niki

Thanks for the response. I currently display the absolute and
elapsed
times using a high res timer, which is how I can see the difference
between the expected and actual timings. I guess I could add more
time
displays, but it would generate a lot of output, and whilst it
might
tell
me when and where in my code the excess time is taken, I am not
sure
it
will necessarily tell me why. I don't think it is my code (they all
say
that), because it is so random.

Is it really random? How can you know without knowing where it
happens?
I
thought all you knew was that it doesn't happen every time?

Did you analyze the time delta's? How are they distributed? Is there
a
normal distribution around 300 ms plus some peaks at 2,5 s? If so,
did
you
check where those peaks are? (I always dump output like that to a
text
file and use Excel to analyze it later)

- Monitor the .NET performance counters. Is there maybe some
correlation
to GC collection or some other runtime event?

How can I tell when garbage collection occurs?

I have a German windows version, so I can't tell you the exact name
of
the
performance counter, should be something like "Number of GCs" in the
".NET
Memory" performance counters section. It increases by one with each
GC
collection. Use perfmon to record it while you test your app.

- Which GC do you use?

How many are there? I thought there was just the one, built-in to
the
framework.

MSDN Quote: "The CLR has two different GCs: Workstation
(mscorwks.dll)
and
Server (mscorsvr.dll). When running in Workstation mode, latency is
more
of a concern than space or efficiency. A server with multiple
processors
and clients connected over a network can afford some latency, but
throughput is now a top priority. Rather than shoehorn both of these
scenarios into a single GC scheme, Microsoft has included two
garbage
collectors that are tailored to each situation."
[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetperftechs.asp]

You'll have to host the runtime to choose between the two, but I
think
the
workstation version is the better choice for you anyway.

Niki
 
Back
Top