AnsweredAssumed Answered

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

Question asked by JPHILLI2_TXDOT on Jan 16, 2020
Latest reply on Jan 17, 2020 by JPHILLI2_TXDOT

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));
            }

        }
    }
}

Outcomes