Search code examples
.netperformancecomarcobjects

Why is my code not using available processor cycles?


I have written a plugin for ESRI ArcEditor that runs some validation checks on a road network. To check if the rules are all satisfied, it basically does a whole bunch of different intersects, with some buffering and envelopes etc. on the selected features.

It has been written in C#.

Now what I am noticing is that it really takes a long time to run the given algorithms on the selected features. I loaded up ANTS profiler and optimized the bottlenecks until there is very little else I can do.

A strange thing I noticed is that ANTS reported virtually no CPU usage in the timeline - a flatline. I then verified that the processor stays below about 10% to 15% using Task Manager while the validation operation is running. This makes no sense to me. Why is it not using available processor cycles?

There is no I/O that is happening as it loads everything from ArcSDE. I also verified that there is no appreciable network traffic during the validation process, thinking it was perhaps waiting for coms between ArcEditor and the server. I then checked the processors on the server just to make sure that no processing was being delegated to it, but it's CPU usage remained steady on 1% during the validation process.

I then thought that ArcEditor is perhaps suppressing the priority that it's plugins can run in, or something crazy like that. So I plugged in a maths op that would max out the CPU for about 10 secs, instead of the validation routine, and it did just that. CPU usage was steady at just over 50%, which makes sense as the maths op would max out one of the cores of my Core 2 Duo. So no luck there. And there is more than 1GB RAM available.

Lastly, I have been trying to find the problem with perfmon, but have had no luck there. Haven't had much experience with it, but can't find anything wrong.

Is it because of ArcObjects COM interface? Although I did also check .NET Interop counters with perfmon.

I am at a loss.

So any help or tips would be greatly appreciated.


Solution

  • Could be a threading problem. COM will automatically marshal method calls on a COM interface to the proper thread. Which is usually the UI thread of the program. This is very slow since it requires a thread context switch and the UI thread must be in a state to dispatch the call. Few CPU cycles are burned, everything is blocking until the call can complete.

    Use the COM object on the same thread as it was created. Which ought to be the UI thread if this the object has STA requirements. They usually do.