Release locked gdb

1889
4
07-16-2013 02:44 AM
AlessandroDiolosa
New Contributor
Hi,
i work with my team in a standalone application using ArcObjects. I simply try to:
- create a new .mxd;
- insert 2 new data frames;
- add a new feature layers to each added data frame. Each new feature layer points to a feature class in a local geodb (at file system).

The problem occurs after mxd is created: geodb at file system is locked then can't be renamed or deleted.

Can someone help me??

This is my code:


Public Sub TestLock()

            Dim pDocClassOut As MxDocumentClass = Nothing
            Dim pObjectCopy As IObjectCopy = Nothing
            Dim appl As IApplication = Nothing
            Dim iNumLock As Integer = 0

            Using comRel As ESRI.ArcGIS.ADF.ComReleaser = New ESRI.ArcGIS.ADF.ComReleaser()

                Try
                    'apre mxd di output
                    Dim strPathOutput As String = String.Empty
                    pDocClassOut = New MxDocumentClass()
                    appl = TryCast(pDocClassOut.Parent, IApplication)
                    appl.Visible = False
                    Dim mxDoc As IMxDocument = TryCast(appl.Document, IMxDocument)
                    comRel.ManageLifetime(mxDoc)

                    Dim objFactory As IObjectFactory = TryCast(appl, IObjectFactory)

                    Dim actContView As IContentsView = mxDoc.ContentsView(0)
                    actContView.Activate(appl.hWnd, mxDoc)
                    mxDoc.CurrentContentsView = actContView


                    Dim strNomeGeoDb As String = "E:\Temp\23TestLock.gdb"
                    Dim strNomeFC() As String = {"CDB_FCLTY_POINT", "CDB_FCLTY_LINE", "CDB_FCLTY_POINT"}

                    'apre geodb
                    'Dim gdbFactType As Type = GetType(FileGDBWorkspaceFactoryClass)
                    'Dim typeClsID As String = gdbFactType.GUID.ToString("B")
                    'Dim wksFactory As IWorkspaceFactory = DirectCast(objFactory.Create(typeClsID), IWorkspaceFactory)

                    Dim factoryType As Type = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory")
                    Dim wksFactory As IWorkspaceFactory = CType(Activator.CreateInstance(factoryType), IWorkspaceFactory)
                    comRel.ManageLifetime(wksFactory)
                    Dim pWks As IWorkspace = wksFactory.OpenFromFile(strNomeGeoDb, 0)
                    comRel.ManageLifetime(pWks)

                    For idx As Integer = 0 To 2

                        'apre FC
                        Dim outFWKS As IFeatureWorkspace = CType(pWks, IFeatureWorkspace)
                        comRel.ManageLifetime(outFWKS)
                        Dim newFC As IFeatureClass = outFWKS.OpenFeatureClass(strNomeFC(idx))
                        'comRel.ManageLifetime(newFC)

                        'crea il DF nella destinazione
                        If idx <> 0 Then
                            Dim pUID As New UID
                            Dim pCmdItem As ICommandItem
                            ' Use the GUID of the Save command
                            pUID.Value = "{C22579D5-BC17-11D0-8667-0000F8751720}"
                            pUID.SubType = 3
                            'comRel.ManageLifetime(pUID)
                            pCmdItem = appl.Document.CommandBars.Find(pUID)
                            pCmdItem.Execute()
                            'comRel.ManageLifetime(pCmdItem)
                            If pCmdItem IsNot Nothing Then
                                System.Runtime.InteropServices.Marshal.ReleaseComObject(pCmdItem)
                            End If
                            If pUID IsNot Nothing Then
                                System.Runtime.InteropServices.Marshal.ReleaseComObject(pUID)
                            End If
                        End If

                        'Dim maps As IMaps = CType(TryCast(appl.Document, IMxDocument).Maps, IMaps)
                        'If idx <> 0 Then
                        '    Dim pMap1 As IMap = New MapClass
                        '    pMap1.Name = "ciccio2"
                        '    maps.Add(pMap1)
                        '    comRel.ManageLifetime(pMap1)
                        'End If

                        'Recupera il DF
                        Dim maps As IMaps = CType(TryCast(appl.Document, IMxDocument).Maps, IMaps)
                        Dim map As IMap = maps.Item(idx)
                        map.Name = "Data frame " & idx.ToString()
                        map.Description = "Descr"

                        'attiva il dataframe corrente
                        Dim activeView As IActiveView = mxDoc.ActiveView
                        activeView.Activate(appl.hWnd)
                        'comReleaser.Add(activeView)
                        If TypeOf (activeView) Is IPageLayout Then
                            mxDoc.ActiveView.FocusMap = map
                            'comRel.ManageLifetime(mxDoc.ActiveView.FocusMap)
                        Else
                            mxDoc.ActiveView = CType(map, IActiveView)
                            'comRel.ManageLifetime(mxDoc.ActiveView)
                        End If
                        'map = mxDoc.ActiveView.FocusMap

                        'crea il layer
                        Dim fcLay As IFeatureLayer = DirectCast(objFactory.Create("esriCarto.FeatureLayer"), IFeatureLayer)
                        'Dim fcLay As IFeatureLayer = New FeatureLayer
                        fcLay.Name = "Lay" & idx.ToString()
                        fcLay.FeatureClass = newFC
                        'comRel.ManageLifetime(fcLay)
                        'comRel.ManageLifetime(fcLay.FeatureClass)

                        'aggiunge layer alla mappa
                        map.AddLayer(fcLay)

                        If fcLay IsNot Nothing Then
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(fcLay)
                        End If
                        If map IsNot Nothing Then
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(map)
                        End If
                        If newFC IsNot Nothing Then
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(newFC)
                        End If
                    Next

                    mxDoc.CurrentContentsView = mxDoc.ContentsView(0)
                    mxDoc.UpdateContents()

                    'appl.SaveDocument()
                    appl.SaveAsDocument("E:\DEV EnGIS\Untitled.mxd")

                    If pWks IsNot Nothing Then
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(pWks)
                    End If
                    If wksFactory IsNot Nothing Then
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(wksFactory)
                    End If
                Catch ex As COMException
                    Return
                Finally
                    appl.Shutdown()

                    'eseguiti in ogni caso anche se si passa per un return
                    If pDocClassOut IsNot Nothing Then
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(pDocClassOut)
                    End If
                    If appl IsNot Nothing Then
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(appl)
                    End If

                    pDocClassOut = Nothing
                    pObjectCopy = Nothing
                End Try

            End Using

            GC.Collect()
            'End Using

End Sub
0 Kudos
4 Replies
DuncanHornby
MVP Notable Contributor
Can you identify for us which line is causing the problem, by colouring it ?
0 Kudos
AlessandroDiolosa
New Contributor
Can you identify for us which line is causing the problem, by colouring it ?



I can't identify what causes the problem. Geodb is surely locked when i open feature classes:
 Dim newFC As IFeatureClass = outFWKS.OpenFeatureClass(strNomeFC(idx))


but i don't know why it is not released. As you can see in originally code i release every single object with:
System.Runtime.InteropServices.Marshal.ReleaseComObject(pCmdItem)


and before i also tryed to release with other suggested techniques as:
Using comRel As ESRI.ArcGIS.ADF.ComReleaser = New ESRI.ArcGIS.ADF.ComReleaser()


A strange thing is that if I insert only one data frame in mxd and all layers inside this data frame everything work correctly and resources are all released. Problem arises when i insert layers in more than one data frame.

Other interesting thing is: Code I posted originally use IObjectFactory to create objects; using this creation method everything work correctly but it is not the right method cause it create other problems elsewhere. The right creation method with "new" statement for coclass and "Activator" for standalone objects have this lock problems.

To test my problem only copy/paste my code in a standalone application (VB.NET) VS2010, replace IObjectFactory with "new" statement and execute. When function return, the mxd is correctly saved with data frame and layers but geodb folder can't be deleted.
0 Kudos
DuncanHornby
MVP Notable Contributor
You say you are making a stand alone application, I assume you are using Engine? I looked at the help for the IMaps interface and in the remarks it says:

... IMaps interface is NOT available with ArcGIS for Server and ArcGIS Engine since this interface is used to get access to a Maps object, which is a non-creatable object. References to non-creatable objects must be obtained through other objects. IMaps interface is available only with ArcGIS for Desktop.


Your code is accessing an MXDocument class? Have you considered using a MapDocument object instead? Look a the help page "Working with map documents" there is a section about why you would use a MapDocument class instead of an MXDocument Class. Worth a read?

Duncan
0 Kudos
AlessandroDiolosa
New Contributor
Hi,
first of all, thank you for reply.

I'm using ArcGis Desktop. My standalone application use an IMxDocument as you can see in code.

When i started writing this project i considered using IMapDocument but i couldn't find a method to insert new data frame in my Mxd. This is a necessary step in my work.
0 Kudos