views:

204

answers:

4

I have single-thread windows form application written with VB.NET and targeting Framework 1.1. The software communicates with external boards through a serial interface, and it mainly consist of a state machine that run some tests, driven in a loop done with a Timer and an Interval of 50ms.

The feedback on the user interface is done through some custom events raised during the tests.

The problem that is driving me crazy is that the performance slightly decrease over time, and in particular after 1200/1300 test operations. The memory occupied does not increase over time, it is only the CPU that seems interested by this problem.

The strange thing is that, targeting framework 2.0 and using the same identical code, I do not have this problem.

I know that is difficult without looking at the code, but do you have suggestions how can I approach the problem?

EDIT: I am really lost, after a couple of intensive work the application starts slowing down. The selected row is related to its process, if it could help.

EDIT2: Using the Windows Task Manager I detected that the Handles counter is increased by 1 at the end of each operation. I don't know if it is the cause but the application starts to slow down when the handles counter reaches about 1500 handles. I checked that all necessary RemoveHandler are called after each operation. Any idea?

EDIT3: I found that the handles problem is generated by the C++ library we are using to communicated with the serial device. It then happens both in .NET 1.1 and .NET 2.0. The difference, and that's strange, is that if the target .NET 1.1 the application slow down/freeze instead for .NET 2.0 I reached more than 30000 handles without loosing performances. Now I don't know if the problem is really caused by this lost handles, I will try to ask to the developers of C++ library to correct the problem and see if it solves the problem I am having on .NET 1.1.

full image here

alt text

+2  A: 

Full disclosure: I am on the Visual Studio Profiler team.

Edit: the following is not useful since the VS Profiler does not work with .NET 1.1. Have you tried running your code under a profiler? Visual Studio 2005/2008 (Developmen Edition/Team Suite) and Visual Studio 2010 Premium/Ultimate have a built-in profiler. There are also 3rd party .NET profilers available.

Running your code under the profiler will show you where your CPU is doing a lot of work. If you profile only around the time when performance is degraded, the results should help you see why.

Alternatively, you can simulate cheap profiling: debug your application and break into it periodically to see what's executing on the call stack.


Also, does your machine have .NET Framework 1.1 SP1 installed? Are you able to reproduce this issue on other machines?

Chris Schmich
@chris thank you for support. The issue can be reproduced in different machines, and in all of them SP1 is installed. I did the cheap profiling that you suggested and also print out the stack level of routines but it seems that stack level is low and not growing, less than 50 always. Do you think that it is possible attaching the VS Premium Profiler to .NET 1.1 while it running?
marco.ragogna
Sorry, I actually forgot, the VS Profiler does not work with .NET 1.1., so no, you can't use that. For the "cheap profiling method", don't worry about the depth of the stack, just break periodically (10 times or so), and keep track of what's executing. If you consistently see the same method(s) executing on top of the stack, then that should help narrow down where the problem is.
Chris Schmich
+1  A: 

First, I would use the Performance profiler included in windows pretty much as Tess suggests here.

Then I would use windbg much as she suggests here.

I only suggest windbg second because if you have not used it you are in for a little WTF session until you get it (it is entirely worth getting though). Maybe by playing around with counters you can find the issue.

Flory
+2  A: 

OK, since you can't use the Performance Profiler, I can think of two things to try.

1) It's the dumb/obvious question. Are you absoutely sure you're Disposing everything that implements IDispose?
Even if you are sure go back and check again, keep an eye out for temporary objects that won't be disposed e.g.

   string s = objA.GetAThing().ToString()

where GetAThing() returns an object that implements IDispose.

2) Have you tried forcing a Garbage Collection?
Read Rico Mariani's Performance Tidbits, sometimes it's not only OK to call GC.Collect(), sometimes it's necessary.
We have a large rich .Net winforms application that on which we need to force a collection every ten minutes or so. If we don't the the application starts to grind after a couple of hours.

Hope this helps :)

UPDATE
Thats a shame. Do you have the C++ source? Or are you stuck with this problem?

If stuck, you can have the application periodically launch a new instance while terminating the current instance.

You can use a locked file or Mutex to ensure the new instance doesn't start processing until the first terminates.

Binary Worrier
Thank you for answering, but I found that the handles problem is generated by the C++ library we are using to communicated with the serial device. It then happens both in .NET 1.1 and .NET 2.0. The difference, and that's strange, is that if the target .NET 1.1 the application slow down/freeze instead for .NET 2.0 I reach more than 30000 handles without loosing performances.
marco.ragogna
+1  A: 

Hmmm

With such limited information it could be a million things.

Using a bit of 'Zen' programming I'd say, get rid of the timer and start using Threads.

Use the usual patterns of having a cancel flag, and have the tests run in an a while loop (if that's how its needed).

Darknight