Schema Locks persisting after running MapView.Active.Map.RemoveStandaloneTables() (ArcGIS Pro SDK C#)

654
5
Jump to solution
01-16-2020 07:57 AM
JohnPhillipsGeo
New Contributor III

Hello,

I am attempting to remove some standalone tables from a map and subsequently launch a Python script that does some work on them.


Here is the code I am using:

The appendOptionAsync() call removes the tables from the map in preparation to run the python script. 

Note that if I right click and remove the tables the locks disappear:

Before:

After:

However, if I run the tool and remove the tables that way... The locks persist

Leading to this error:

The locks remain even after I click out of the Python window:

However... as soon as I click the button to run the tool again, the locks disappear:

Before:

Immediately after clicking the Import button again (locks are cleared):

I feel like this might have something to do with garbage collection so I attempted to go back and put "using" statements as well as Dispose statements on the tables.


The launchBaconAsync() call launches the python script.

Thank you

-John

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Oracle.ManagedDataAccess.Client;


namespace BulkLoadTool
{
    internal class Bacon : Button
    {

        public static IEnumerable<List<T>> SplitList<T>(List<T> locations, int nSize = 1000)
        {
            for (int i = 0; i < locations.Count; i += nSize)
            {
                yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i));
            }
        }

        public async void appendOptionAsync()
        {
            await QueuedTask.Run(() =>
            {
                string selGDBitem = Module1.Current.GDBdropdown.SelectedItem.ToString();

                if (selGDBitem == "" || selGDBitem == null)
                {

                    using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                    {
                        appFile.Write(String.Format("{0},\"{1}\"", "False", ""));
                    }
                    return;
                }

                else
                {
                    string appString = String.Format("Would you like to append to {0}?", selGDBitem);
                    var appResult = ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(appString, "Append Features", MessageBoxButton.YesNo, MessageBoxImage.Information);
                    if (appResult == MessageBoxResult.Yes)
                    {                      

                        using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                        {

                            try
                            {

                                appFile.Write(String.Format("{0},\"{1}\"", "True", selGDBitem));
                            IReadOnlyList<StandaloneTable> standAloneTables = MapView.Active.Map.StandaloneTables;
                            List<StandaloneTable> removalStandAloneTables = new List<StandaloneTable>();

                            foreach (var sATbl in standAloneTables)
                            {
                                string sAPath = sATbl.GetTable().GetDatastore().GetPath().ToString();
                                if (sAPath.Contains(selGDBitem))
                                Trace.WriteLine(sAPath);
                                {
                                    removalStandAloneTables.Add(sATbl);
                                    sATbl.GetTable().Dispose();
                                    
                                }                                                                
                            }

                            Trace.WriteLine(selGDBitem);

                            MapView.Active.Map.RemoveStandaloneTables(removalStandAloneTables);
                            
                                var dispData = removalStandAloneTables.First().GetTable().GetDatastore().GetPath().AbsolutePath;
                            }
                            catch
                            {

                            }

                            return;

                        }
                        
                    }
                                                                          
                    else
                        using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                        {
                            appFile.Write(String.Format("{0},\"{1}\"", "False", ""));
                        }
                    return;
                }
            });
        }

        public async void launchBaconAsync()
        {
            try
            {
                await QueuedTask.Run(() =>
                {

                    object myCommand = @"C:\TxDOT\BulkLoad\LayerReference\Scripts\FutureBacon.bat";

                    System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c" + myCommand);

                    procStartInfo.RedirectStandardOutput = false;
                    procStartInfo.UseShellExecute = true;
                    procStartInfo.CreateNoWindow = false;

                    System.Diagnostics.Process proc = new System.Diagnostics.Process();
                    proc.StartInfo = procStartInfo;
                    proc.Start();

                    //string result = proc.StandardOutput.ReadToEnd();
                    string result = String.Format("Features selected.  See Python Window");
                    //ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(result);
                });
            }
            catch (Exception e)
            {
                ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(e.Message);
            }
        }

        protected override void OnClick()
        {
            try
            {
                var prog = new ProgressDialog("Gathering Route Info...", false);
                prog.Show();

                QueuedTask.Run(() =>
                {
                    var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().First(l => l.Name.Contains("TxDOT_Roadways_Edits"));
                    var selectionfromMap = lyr.GetSelection();

                    var gidList = new List<string>();
                    var oids = selectionfromMap.GetObjectIDs().ToList();
                    int count = oids.Count();

                    var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector(false);

                    Dictionary<string, Dictionary<string, string>> futureDict = new Dictionary<string, Dictionary<string, string>>();



                    foreach (var oid in oids)
                    {
                        insp.Clear();
                        insp.Load(lyr, oid);

                        Dictionary<string, string> futureNestedDict = new Dictionary<string, string>();


                        var gid = insp["GID"].ToString();
                        var editOp = insp["EDIT_TYPE"].ToString();

                        //FUTURE BACON DICT PARAMETERS
                        var OGEOMS = insp["OGEOMS"].ToString();
                        var BEGIN_DFO = insp["BEGIN_DFO"].ToString();
                        var END_DFO = insp["END_DFO"].ToString();
                        var ETL_JOB_ID = insp["ETL_JOB_ID"].ToString();

                        if (editOp.Contains("Retire")) { continue; };

                        futureNestedDict["OGEOMS"] = OGEOMS;
                        futureNestedDict["BEGIN_DFO"] = BEGIN_DFO;
                        futureNestedDict["END_DFO"] = END_DFO;
                        futureNestedDict["ETL_JOB_ID"] = ETL_JOB_ID;
                        futureNestedDict["IN_GRID"] = "True";

                        futureDict[gid] = futureNestedDict;
                        gidList.Add(gid);
                    }

                    List<string> removeGidList = new List<string>(gidList);


                    using (OracleConnection oc = new OracleConnection())
                    {
                        oc.ConnectionString = "Data Source=*******;USER ID=*********;Password=*******";
                        oc.Open();

                        var chunks = SplitList(gidList);

                        foreach (var chunk in chunks)
                        {


                            var chunkListJoin = String.Join(",", chunk);
                            string sql = String.Format("SELECT RDBD_GMTRY_LN_ID FROM GRIDOP.RDBD_GMTRY_LN WHERE GRIDOP.RDBD_GMTRY_LN.RDBD_GMTRY_LN_ID IN ({0})", chunkListJoin);
                            OracleDataAdapter oda = new OracleDataAdapter(sql, oc);
                            DataTable dt = new DataTable();
                            oda.Fill(dt);

                            foreach (DataRow dr in dt.Rows)
                            {
                                removeGidList.Remove(dr[0].ToString());
                            }

                        };
                        Trace.WriteLine("Not in GRID: ");
                        Trace.WriteLine(String.Join(",", removeGidList));
                        Trace.WriteLine("In GRID: ");
                        Trace.WriteLine(String.Join(",", gidList));

                        foreach (var g in removeGidList)
                        {
                            futureDict[g]["IN_GRID"] = "False";
                        }

                        oc.Close();
                    }

                    //Write string to file
                    System.IO.FileInfo file = new System.IO.FileInfo(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\futureBaconDict.log");
                    file.Directory.Create();
                    using (var outFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\futureBaconDict.log"))
                    {
                        long gCount = gidList.Count();
                        long curCount = 1;

                        foreach (var arr in gidList)
                        {
                            if (curCount == 1)
                            {
                                outFile.Write("{");
                            }

                            //System.Diagnostics.Trace.WriteLine(arr);
                            //System.Diagnostics.Trace.WriteLine(futureDict[arr]);
                            String dString = String.Format("{0}:{{\"OGEOMS\":\"{1}\",\"BEGIN_DFO\":{2},\"END_DFO\":{3}}}",
                                arr,
                                futureDict[arr]["OGEOMS"],
                                futureDict[arr]["BEGIN_DFO"],
                                futureDict[arr]["END_DFO"]);

                            outFile.Write(dString);
                            if (curCount < gCount)
                            {
                                outFile.Write(",");
                            }
                            else
                            {
                                outFile.Write("}");
                            }
                            curCount = curCount + 1;
                        }
                    }

                });

                prog.Dispose();


                //Check append option
                appendOptionAsync();                

                launchBaconAsync();

                return;
            } 

            catch (Exception e)
            {
                Trace.WriteLine(e.Message);

                //Module1.CreateNotification("Adding Layer... Will take a minute or so", "Roadways Edits Not Found");
                //, @"Images\Bacon16.png");


                var Datapath = QueuedTask.Run(() =>
                {

                    DatabaseConnectionProperties connectionProperties = new DatabaseConnectionProperties(EnterpriseDatabaseType.SQLServer)
                    {
                        AuthenticationMode = AuthenticationMode.OSA,
                        Instance = ***************
                        Database = *************
                        Version = **********
                    };


                    using (Geodatabase enterpriseGeodatabaseViaConnectionProperties = new Geodatabase(connectionProperties))
                    {

                        var gdbPath = enterpriseGeodatabaseViaConnectionProperties.GetPath();
                        return gdbPath.LocalPath;
                    }
                });

                string rdwaysEnd = @"TPP_GIS.APP_TPP_GIS_ADMIN.Roadways_Edits\TPP_GIS.APP_TPP_GIS_ADMIN.TxDOT_Roadways_Edits";
                string fullRdwayPath = Path.Combine(Datapath.Result, rdwaysEnd);
                Uri rdUri = new Uri(fullRdwayPath);

                QueuedTask.Run(() => LayerFactory.Instance.CreateLayer(rdUri, MapView.Active.Map));
            }

        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

0 Kudos
1 Solution

Accepted Solutions
RichRuh
Esri Regular Contributor

John,

I haven't analyzed all of your code, but this loop in AppendOptionAsync is going to keep locks around:

if (sATbl.GetTable().GetDatastore().GetPath().ToString().Contains(selGDBitem))
{
  removalStandAloneTables.Add(sATbl);
  sATbl.GetTable().Dispose();                                 
}   

Here's a better way to do this:

using (Table myTable = sATbl.GetTable())
using (Datastore myDatastore = myTable.GetDatastore())
{  
  if (myDatastore.GetPath().ToString().Contains(selGDBitem)) {
    removalStandAloneTables.Add(sATbl);
  }
}
 

Here I'm disposing both the table and the datasource. 

Likewise, this code isn't doing what you want it to:

foreach (var t in removalStandAloneTables)
{
  t.GetTable().Dispose();
}

removalStandAloneTables.First().GetTable().GetDatastore().Dispose();
‍‍‍‍‍

The loop portion is getting a table pointer, and then removing it (no effect whatsoever).

The last line is getting a table point, then getting a datastore pointer, then disposing the datastore pointer (leaving the table pointer behind).

You can remove this entire code block.

There's more documentation on how to properly dispose of geodatabase objects here.

--Rich

View solution in original post

5 Replies
RichRuh
Esri Regular Contributor

I haven't analyzed the entire code snippet, but this line:

var dispData = removalStandAloneTables.First().GetTable().GetDatastore().GetPath().AbsolutePath;
                            }

Is going to create a Table and a Geodatabase object that are not disposed.  They could keep a lock until .NET garbage collection runs.

0 Kudos
JohnPhillipsGeo
New Contributor III

Rich,

I was able to completely remove that line as it wasn't being used anymore (it was from some previous troubleshooting)

The weird thing is that as soon as I press the button again, the locks immediately disappear. 

Is there a method to check for and clear locks specifically?

Thanks!

JP

0 Kudos
JohnPhillipsGeo
New Contributor III

Rich,

I cleaned up the appendOptionAsync() code (where the error is occurring) so that the QueuedTask only runs on the for loop.

I then attempted to RemoveStandaloneTables outside of that QueuedTask and got a different error:

Exception thrown: 'System.UnauthorizedAccessException' in ArcGIS.Desktop.Mapping.dll
An exception of type 'System.UnauthorizedAccessException' occurred in ArcGIS.Desktop.Mapping.dll but was not handled in user code
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

I think this may mean that the locks are somehow persisting inside of that loop. 

Anyways, thanks for the help just wanted to throw that out there.

JP

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Oracle.ManagedDataAccess.Client;


namespace BulkLoadTool
{
    internal class Bacon : Button
    {

        public static IEnumerable<List<T>> SplitList<T>(List<T> locations, int nSize = 1000)
        {
            for (int i = 0; i < locations.Count; i += nSize)
            {
                yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i));
            }
        }

        public async void appendOptionAsync()
        {

            string selGDBitem = Module1.Current.GDBdropdown.SelectedItem.ToString();
                
                if (selGDBitem == "" || selGDBitem == null)
                {

                    using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                    {
                        appFile.Write(String.Format("{0},\"{1}\"", "False", ""));
                    }
                    return;
                }

                else
                {
                    string appString = String.Format("Would you like to append to {0}?", selGDBitem);
                    var appResult = ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(appString, "Append Features", MessageBoxButton.YesNo, MessageBoxImage.Information);
                    if (appResult == MessageBoxResult.Yes)
                    {                      

                        using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                        {
                            //try
                            //{

                            appFile.Write(String.Format("{0},\"{1}\"", "True", selGDBitem));
                            IReadOnlyList<StandaloneTable> standAloneTables = MapView.Active.Map.StandaloneTables;
                            List<StandaloneTable> removalStandAloneTables = new List<StandaloneTable>();

                        var rStandAloneTables = await QueuedTask.Run(() =>
                        {
                        
                        foreach (var sATbl in standAloneTables)
                            {
                                if (sATbl.GetTable().GetDatastore().GetPath().ToString().Contains(selGDBitem))
                                {
                                    removalStandAloneTables.Add(sATbl);
                                    sATbl.GetTable().Dispose();                                 
                                }                                                                
                            }

                            return removalStandAloneTables;

                        });

                        MapView.Active.Map.RemoveStandaloneTables(rStandAloneTables);
                            
                            foreach (var t in removalStandAloneTables)
                                {
                                    t.GetTable().Dispose();
                                }

                            removalStandAloneTables.First().GetTable().GetDatastore().Dispose();

                            //}
                            //catch
                            //{

                            //}
                            return;
                        }                        
                    }
                                                                          
                    else
                        using (var appFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\appendOption.log"))
                        {
                            appFile.Write(String.Format("{0},\"{1}\"", "False", ""));
                        }
                            return;
                }
            
        }

        public async void launchBaconAsync()
        {
            try
            {
                await QueuedTask.Run(() =>
                {

                    object myCommand = @"C:\TxDOT\BulkLoad\LayerReference\Scripts\FutureBacon.bat";

                    System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c" + myCommand);

                    procStartInfo.RedirectStandardOutput = false;
                    procStartInfo.UseShellExecute = true;
                    procStartInfo.CreateNoWindow = false;

                    System.Diagnostics.Process proc = new System.Diagnostics.Process();
                    proc.StartInfo = procStartInfo;
                    proc.Start();

                    //string result = proc.StandardOutput.ReadToEnd();
                    string result = String.Format("Features selected.  See Python Window");
                    //ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(result);
                });
            }
            catch (Exception e)
            {
                ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(e.Message);
            }
        }

        protected override void OnClick()
        {
            try
            {
                var prog = new ProgressDialog("Gathering Route Info...", false);
                prog.Show();

                var result = QueuedTask.Run(() =>
                {
                    var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().First(l => l.Name.Contains("TxDOT_Roadways_Edits"));
                    //var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
                    var selectionfromMap = lyr.GetSelection();

                    var gidList = new List<string>();
                    //var removeGidList = new List<string>();

                    var oids = selectionfromMap.GetObjectIDs().ToList();
                    int count = oids.Count();

                    var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector(false);

                    Dictionary<string, Dictionary<string, string>> futureDict = new Dictionary<string, Dictionary<string, string>>();

                    foreach (var oid in oids)
                    {
                        insp.Clear();
                        insp.Load(lyr, oid);

                        Dictionary<string, string> futureNestedDict = new Dictionary<string, string>();


                        var gid = insp["GID"].ToString();
                        var editOp = insp["EDIT_TYPE"].ToString();

                        //FUTURE BACON DICT PARAMETERS
                        var OGEOMS = insp["OGEOMS"].ToString();
                        var BEGIN_DFO = insp["BEGIN_DFO"].ToString();
                        var END_DFO = insp["END_DFO"].ToString();
                        var ETL_JOB_ID = insp["ETL_JOB_ID"].ToString();

                        if (editOp.Contains("Retire")) { continue; };

                        futureNestedDict["OGEOMS"] = OGEOMS;
                        futureNestedDict["BEGIN_DFO"] = BEGIN_DFO;
                        futureNestedDict["END_DFO"] = END_DFO;
                        futureNestedDict["ETL_JOB_ID"] = ETL_JOB_ID;
                        futureNestedDict["IN_GRID"] = "True";

                        futureDict[gid] = futureNestedDict;

                        //System.Diagnostics.Trace.WriteLine(gid);

                        gidList.Add(gid);
                    }

                    List<string> removeGidList = new List<string>(gidList);


                    using (OracleConnection oc = new OracleConnection())
                    {
                        oc.ConnectionString = "Data Source=********;USER ID=*********;Password=*******";
                        oc.Open();

                        var chunks = SplitList(gidList);

                        foreach (var chunk in chunks)
                        {


                            var chunkListJoin = String.Join(",", chunk);
                            string sql = String.Format("SELECT RDBD_GMTRY_LN_ID FROM GRIDOP.RDBD_GMTRY_LN WHERE GRIDOP.RDBD_GMTRY_LN.RDBD_GMTRY_LN_ID IN ({0})", chunkListJoin);
                            OracleDataAdapter oda = new OracleDataAdapter(sql, oc);
                            DataTable dt = new DataTable();
                            oda.Fill(dt);

                            foreach (DataRow dr in dt.Rows)
                            {
                                removeGidList.Remove(dr[0].ToString());
                            }

                        };
                        Trace.WriteLine("Not in GRID: ");
                        Trace.WriteLine(String.Join(",", removeGidList));
                        Trace.WriteLine("In GRID: ");
                        Trace.WriteLine(String.Join(",", gidList));

                        foreach (var g in removeGidList)
                        {
                            futureDict[g]["IN_GRID"] = "False";
                        }

                        oc.Close();
                    }

                    //Write string to file
                    System.IO.FileInfo file = new System.IO.FileInfo(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\futureBaconDict.log");
                    file.Directory.Create();
                    //System.IO.File.WriteAllLines(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\writeGIDs.log", gidList.Select(x => string.Join(",", x)));
                    using (var outFile = System.IO.File.CreateText(@"C:\TxDOT\BulkLoad\LayerReference\configFiles\futureBaconDict.log"))
                    {
                        long gCount = gidList.Count();
                        long curCount = 1;

                        foreach (var arr in gidList)
                        {
                            if (curCount == 1)
                            {
                                outFile.Write("{");
                            }

                            //System.Diagnostics.Trace.WriteLine(arr);
                            //System.Diagnostics.Trace.WriteLine(futureDict[arr]);
                            String dString = String.Format("{0}:{{\"OGEOMS\":\"{1}\",\"BEGIN_DFO\":{2},\"END_DFO\":{3}}}",
                                arr,
                                futureDict[arr]["OGEOMS"],
                                futureDict[arr]["BEGIN_DFO"],
                                futureDict[arr]["END_DFO"]);

                            //String dString = String.Format("{0}:{{\"OGEOMS\":\"{1}\",\"IN_GRID\":{2}}}"
                            //String dString = String.Format("{0}:{{\"OGEOMS\":\"{1}\"}}",
                            //    arr,
                            //    futureDict[arr]["OGEOMS"]
                            //    );
                            //,
                            //futureDict[arr]["IN_GRID"]);

                            outFile.Write(dString);
                            if (curCount < gCount)
                            {
                                outFile.Write(",");
                            }
                            else
                            {
                                outFile.Write("}");
                            }
                            curCount = curCount + 1;
                        }
                    }

                });

                prog.Dispose();


                //Wait for Task to finish
                result.Wait();

                appendOptionAsync();
                GC.Collect();
                GC.WaitForPendingFinalizers();

                launchBaconAsync();

                return;
            }

            catch (Exception e)
            {
                Trace.WriteLine(e.Message);
                return;

                //Module1.CreateNotification("Adding Layer... Will take a minute or so", "Roadways Edits Not Found");
                //, @"Images\Bacon16.png");


                var Datapath = QueuedTask.Run(() =>
                {

                    DatabaseConnectionProperties connectionProperties = new DatabaseConnectionProperties(EnterpriseDatabaseType.SQLServer)
                    {
                        *********
                    };


                    using (Geodatabase enterpriseGeodatabaseViaConnectionProperties = new Geodatabase(connectionProperties))
                    {

                        var gdbPath = enterpriseGeodatabaseViaConnectionProperties.GetPath();
                        return gdbPath.LocalPath;
                    }
                });

                string rdwaysEnd = @"TPP_GIS.APP_TPP_GIS_ADMIN.Roadways_Edits\TPP_GIS.APP_TPP_GIS_ADMIN.TxDOT_Roadways_Edits";
                string fullRdwayPath = Path.Combine(Datapath.Result, rdwaysEnd);
                Uri rdUri = new Uri(fullRdwayPath);

                QueuedTask.Run(() => LayerFactory.Instance.CreateLayer(rdUri, MapView.Active.Map));
            }

        }
    }
}

0 Kudos
RichRuh
Esri Regular Contributor

John,

I haven't analyzed all of your code, but this loop in AppendOptionAsync is going to keep locks around:

if (sATbl.GetTable().GetDatastore().GetPath().ToString().Contains(selGDBitem))
{
  removalStandAloneTables.Add(sATbl);
  sATbl.GetTable().Dispose();                                 
}   

Here's a better way to do this:

using (Table myTable = sATbl.GetTable())
using (Datastore myDatastore = myTable.GetDatastore())
{  
  if (myDatastore.GetPath().ToString().Contains(selGDBitem)) {
    removalStandAloneTables.Add(sATbl);
  }
}
 

Here I'm disposing both the table and the datasource. 

Likewise, this code isn't doing what you want it to:

foreach (var t in removalStandAloneTables)
{
  t.GetTable().Dispose();
}

removalStandAloneTables.First().GetTable().GetDatastore().Dispose();
‍‍‍‍‍

The loop portion is getting a table pointer, and then removing it (no effect whatsoever).

The last line is getting a table point, then getting a datastore pointer, then disposing the datastore pointer (leaving the table pointer behind).

You can remove this entire code block.

There's more documentation on how to properly dispose of geodatabase objects here.

--Rich

JohnPhillipsGeo
New Contributor III

Rich,

Thanks for solving yet another one of my issues!  The using statement did the trick.  I didn't realize that I wasn't disposing the underlying datasource correctly. 

I will definitely be using the 'using' statement more.

You are the man!  Have a great weekend and thanks

JP

0 Kudos