ThinkGeo.com    |     Documentation    |     Premium Support

Handle Count is increasing

Hi Ben

Thanks for your explanation.

You wrote: “the GC cannot keep up with releasing the underlying WaitHandle objects”

I do no understand what you mean. Do you mean that it is a bug in .NET ?

Note that in our cases the application was running for 2~3 days and the handle count was over 10000 where 9000 alone was of kind “Event Handler” (from Sysinternals Handle tool).

About replacing LayerOverlay with FeatureLayerWpfDrawingOverlay it is my understanding that it is not possible for me to replace LayerOverlay with FeatureLayerWpfDrawingOverlay for all the cases

Our application uses 6 overlays both because it is requested by the API and also in order to hide/show or refresh a single overlay:

  • An overlay for moving devices
  • An overlay for (semi) static devices like base stations
  • An overlay for geofencing areas
  • An overlay ESRI Shapefiles
  • An overlay for the Graticule Grid
  • An overlay for the base map (Raster, OpenStreetMaps, WMS, …)

At the moment cases 1 to 3 are now using FeatureLayerWpfDrawingOverlay as you suggested. But this is not possible in cases 4 to 6.

OpenStreet maps and WMS maps use their own overlay: WmsOverlay and OpenStreetMapOverlay.

Raster maps (ECW and GeoTiff) are loaded using a GdalRasterLayer and they are added to a LayerOverlay. It is not possible to use FeatureLayerWpfDrawingOverlay in this case.

GraticuleFeatureLayer is raising an exception when used with FeatureLayerWpfDrawingOverlay therefore I am still using LayerOverlay: System.ArgumentOutOfRangeException: The input double value is out of range. (Parameter ‘distance’)

ShapeFileFeatureLayer is also raising an exception when used with FeatureLayerWpfDrawingOverlay therefore I am still using LayerOverlay: The FeatureSource is not open. Please call the Open method before calling this method.

We have just terminated the migration from version 14.6.2 to 14.3.2 and we have performed some quick test in order to check if we cover the previous functionality. We will start long run and handle count test now, but it is my impression that the handle count is still increasing.

I will start 3 long run tests in parallel:

  • Our application with the map view open
  • Our application without the map view open
  • The demo application (the source code is in this thread)

I will collect the handle count on all the 3 cases, and I will report the result in this thread

One last comment. We have observed this in the demo for the case: Map is delaying the process to close - ThinkGeo UI for Desktop / WPF - ThinkGeo Discussion Forums

This entry could be related to this one. We have observed very often that when the application terminates (with a long delay) the last line in Visual Studio Output Window is:

The program ‘[33604] DemoMapStealingFocus.exe’ has exited with code 3221225477 (0xc0000005) ‘Access violation’.

This is also reported in that thread

Best regards

Domenico

Hi Domenico,

We found the simple code as following, run it for a couple hours and the handle count increases. Also in our test the handles don’t drop even after calling GC.Collect(). Please have a try if you are interested.

var timer = new System.Threading.Timer(async _ =>
{
await Task.Run(() => { });
}, null, 0, 1000);

About overlays: each overlay comes with overhead in terms of memory, drawing, and synchronization. To optimize, we recommend consolidating where possible:

  1. Background overlay — keep your base map here.
  2. Static layers — combine ShapeFiles, static stations, and geofencing areas into one TileOverlay (with multi-tiles enabled). Enable tile caching so they do not redraw unnecessarily.
  3. Dynamic layers — use FeatureLayerWpfDrawingOverlay for frequently changing content. This avoids creating large images repeatedly and keeps memory usage lower.

When refreshing, it’s best to avoid calling Map.RefreshAsync() or StaticOverlay.RefreshAsync() since these force overlays to redraw. You can call WpfDrawingOverlay.RefreshAsync() for the dynamic layers. For navigation, use Map.ZoomToAsync() to adjust the extent without redrawing everything.

Thanks,
Ben

Hi Ben

I will just inform you that we had our application running during the weekend and receiving new position on the map without increasing the handle count.

The application was upgraded to ThinkGeo 14.3.2 with the overlay layout as I described in my last post.

We will start tests with user actions (zooming, panning, adding/removing shape files) and measure again the handle count

Best regards
Domenico

That’s great, please keep us posted!

Hi Ben

In a previous post you mentioned that you were able to see a handle count increasing which you point back to Task.Run (which is used when refreshing LayerOverlay).

Where you wrote:

“This isn’t a true leak, but rather a case where the GC cannot keep up with releasing the underlying WaitHandle objects, so it appears like a leak.”

What is ThinkGeo plan? Are you going to perform any action on this topic?

In the meantime, we are still monitoring the handle count in our updated application using ThinkGeo 14.3.2 and your suggested changes.

We would like also to include our customer which experienced the handle count issue, but we are waiting a solution for the crash (0xc0000374 and 0xc0000005) observed when using ECW with ThinkGeo version 14.3.2 (discussion: Map is delaying the process to close - ThinkGeo UI for Desktop / WPF - ThinkGeo Discussion Forums)

Best regards

Domenico

Hi Domenico,

If even the following code shows an increasing handle count, that suggests the way we are currently measuring handle usage may not be accurate, or that’s not a real handle leak

var timer = new System.Threading.Timer(async _ =>
{
    await Task.Run(() => { });
}, null, 0, 1000);

Did you have a chance to run this test on your side and see if the handle count still keeps increasing?

You mentioned earlier that “we had our application running during the weekend and receiving new positions on the map without increasing the handle count.” Does that mean you are now using a different way to measure handle usage? If so, could you share the method with us?

Our plan is to first establish a reliable way to test and verify whether there is a real handle leak. Once we have that, we can investigate further.

Regarding your other post: Map is delaying the process to close, my understanding was that this only happens when closing the application and has nothing to do with the handle leak. Please let me know if I misunderstood.

Thanks,
Ben

Hi Ben

I did not try the Task.Run sampe you sent. I trust in what you say.

I am measuring the handle count always with PerfMonitor from Windows.

Before upgrading to 14.3.2 the handle count in our application was increasing by letting the application running without user actions (only presenting the received positions updates).

After we upgrade to 14.3.2 and performed the suggested changes the same test does not present the increasing handle count.

From my point of view at the moment it seems that the handle count issue is solved by those changes and therefore this case is closed. We will try to load tests with user actions and if we get a different result then I will re-open this case.

Regarding the other post, sorry I mentioned in this post. My reason is that introducing the suggested changes for the Handle count issue has introduced a new problem in the application. I will continue this in the other thread.

Best regards

Domenico

Hi Domenico,

That makes sense. We’ve been able to narrow it down — await Task.Run(() => { }); is what was driving the handle count increase. With your change (especially switching to FeatureLayerWpfDrawingOverlay for the GPS points), that code path is no longer called, which is why the handle count stays stable.

We’ll continue looking into why that specific line causes a leak, but from a user’s perspective, continuously refreshing a single tile overlay (like for GPS updates) isn’t recommended anyway. Your current approach avoids that pattern and should be more efficient.

Thanks,
Ben