Releasing locks on raster objects

06-10-2014 08:52 AM
New Contributor III

I have written a pretty simple add-in (in C# .NET) that does some symbolizing on raster (TIF) layers, changing their renderers in the process.  When I remove these raster layers from ArcMap, sometimes I need to rename them in Windows, but I cannot because a message appears telling me they are still open in ArcMap.  This does not happen if I do not use the add-in on the files.

I have tried using ReleaseComObject on the raster layers before exiting the add-in, but this does not do the trick.  I should point out that when the raster layers are first added to ArcMap, tif.ovr and .tif.aux.xml files are created.  Could the problem have something to do with those?

0 Kudos
3 Replies
MVP Frequent Contributor

It is not clear how you get a handle on the raster. Does your AddIn code do the actual loading of the raster into ArcMap or is it a button that grabs the raster from the TOC (which was manually added by you) and then do some symbolizing?

Without seeing the code one can only speculate. Have you got globals that may be holding a lock? Are you destroying every object including workspaces?

I cobbled some code together from random stumbling around the internet looking at this problem. I often use this in an to clean up.

 Private Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" Alias "SetProcessWorkingSetSize" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer

Public Sub FlushMemory()
    If Environment.OSVersion.Platform = PlatformID.Win32NT Then
        SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1)
    End If
End Sub
0 Kudos
New Contributor III
Unfortunately it is my experience that ArcMap rarely if ever releases locks on features and tables (regardless of the type of data source) before it is closed. So it's always best to exit ArcMap fully before renaming files that you had opened in ArcMap. Any time you use ArcObjects code to open a file, the handle to the file is going to be controlled from within the "unmanaged" memory space of ArcMap, not in the .NET managed memory space of your Add-in, (hence the need for ReleaseComObject) so there isn't really anything you can ultimately do anything about it. Duncan's code appears to be trying to tell Windows to force ArcMap into releasing unused memory, which might work, but I try to avoid that type of fiddling because it can cause unknown problems. I also wonder if it would even do anything on a 64 bit version of Windows, since it checks to see if the Windows version is Win32NT.

Also, one thing you mentioned was that you were trying to call "ReleaseComObject on the raster layers before exiting the add-in". There aren't any semantics for shutting down the Add-in like that. Once an Add-in is loaded into memory, it pretty much stays there until ArcMap is closed. It might be removed from memory if you uninstalled it, but it doesn't go away just because you close windows, hide toolbars, disable commands and tools, or whatever else you have included in your Add-in. It's still there waiting to be used again. You can put breakpoints on the constructors of your commands and see that they aren't ever called a second time by ArcMap. Thus if you have any static references to your layer, or static references to anything that references the layer, it will still be there until ArcMap is shut down. Just FYI. 😉
0 Kudos
Regular Contributor III
When you remove a layer from the map, ArcMap keeps a reference to it so that you can undo the operation using the Undo/ReDo buttons.  So, whenever you remove a layer and want to release any locks that may be on the data source you should call IDataLayer2.Disconnect if the layer implements that interface.  Prior to that you will need to call ReleaseComObject on any ArcObjcts that may reference the data source (namely cursors and feature/row objects but there could be others).  After calling Disconnect, clear the operation stack by calling IMxDocument.OperationStack.Reset.  Finally, call ReleaseComObject on your layer reference.  Hope this helps.
0 Kudos