如何删除使用 ArcObjects 访问的 dbf 文件上的架构锁?

发布于 2024-10-09 15:45:04 字数 3081 浏览 3 评论 0原文

我正在为 ArcGIS Desktop/Server 创建自定义地理处理工具。在工具执行期间,我创建一个 dbf 文件并使用游标访问其内容。该工具完成执行后,该文件上的锁定仍然存在,并且只能通过重新启动 ArcMap/ArcCatalog 来删除。是否有一种编程方法可以删除架构锁?

我已经逐行进入下面的代码。创建 ITable ArcObject 会创建一个以“.sr.lock”结尾的锁定文件,创建 ICursor 对象会在与 dbf 文件相同的目录中创建一个以“.rd.lock”结尾的锁定文件。如果不使用底部的任一 ReleaseComObject 方法,这两个文件都会保留。我可以从游标中删除第二个锁定文件,但不能删除与表关联的锁定文件。即使我删除 dbf 文件,锁定文件仍然存在,并且在 ArcMap/ArcCatalog 关闭之前无法删除父目录。

有代码 此处暗示了一个解决方案,但该代码缺少某些元素。

    public Dictionary<Int32, Dictionary<Int32,Double>> GetTabulatedAreaDict()
    {
        IGPUtilities3 gpUtil = new GPUtilitiesClass();
        Geoprocessor gp = new Geoprocessor();

        //Tabulate Area
        string tableName = "lcAreaByRru.dbf";
        string tablePath = this.tempDirPath + "\\" + tableName;
        TabulateArea tabulateArea = new TabulateArea();
        tabulateArea.in_zone_data = this.rruPath;
        tabulateArea.zone_field = "VALUE";
        tabulateArea.in_class_data = this.rasterValue.GetAsText();
        tabulateArea.class_field = "VALUE";
        tabulateArea.out_table = tablePath;
        gp.Execute(tabulateArea, null);

        // Extract information from table
        IWorkspaceFactory wsf = new ShapefileWorkspaceFactoryClass();
        IWorkspace ws = wsf.OpenFromFile(this.tempDirPath, 0);
        IFeatureWorkspace fws = (IFeatureWorkspace)ws;
        ITable taTable = fws.OpenTable(tableName);// Creates .sr.lock file
        //ITable taTable = gpUtil.OpenTableFromString(tablePath); // Creates .sr.lock file
        ICursor tableRows = taTable.Search(null, false); // Creates .rd.lock file
        IRow tableRow = tableRows.NextRow();
        this.tabulatedAreaDict = new Dictionary<Int32, Dictionary<Int32, Double>>();
        while (tableRow != null)
        {
            Int32 id = (Int32)tableRow.get_Value(1); // Feature ID
            Dictionary<Int32, Double> valueAreaDict = new Dictionary<Int32, Double>();
            for (int i = 2; i < tableRow.Fields.FieldCount; i++)
            {
                int key = int.Parse(tableRow.Fields.get_Field(i).Name.Split('_')[1]);
                double value = (double)tableRow.get_Value(i);
                valueAreaDict.Add(key, value);
            }
            this.tabulatedAreaDict.Add(id, valueAreaDict);
            tableRow = tableRows.NextRow();
        }

        System.Runtime.InteropServices.Marshal.ReleaseComObject(tableRows); //Removes .rd.lock file
        System.Runtime.InteropServices.Marshal.ReleaseComObject(taTable); // Does not remove .sr.lock file

        return this.tabulatedAreaDict;
    }

更新:

我发现dbf没有被锁定,但是有与dbf关联的杂散锁定文件。当 ArcCatalog 仍在运行时,我能够删除该表,但无法删除包含 dbf 的文件夹。使用 ArcCatalog GUI 或 Windows 资源管理器时删除父目录失败。我可以使用Delete_management地理处理工具删除该文件夹。

我曾考虑过使用非 ArcObjects 方法访问 dbf,但我意识到稍后使用要素类和地理数据库可能会遇到此问题,因此最好继续使用 ArcObjects。

为了更好地管理这个问题,我打算在临时工作空间(如果未指定则为系统临时)中创建表,然后在访问完成后将文件移动到正确的目标。

I am creating a custom geoprocessing tool for ArcGIS Desktop/Server. During the tool execution, I create a dbf file and access its contents using a cursor. The lock on this file remains after the tool has finished executing and can only be removed by restarting ArcMap/ArcCatalog. Is there a programmatic method to remove the schema lock?

I have stepped into the code below, line by line. Creation of the ITable ArcObject creates a lock file ending in ".sr.lock" and creating the ICursor object creates a lock file ending in ".rd.lock" in the same directory as the dbf file. Without using either ReleaseComObject method at the bottom, both files persist. I can get the second lock file from the cursor removed but not the one associated with the table. Even if I delete the dbf file, the lock files persist, and the parent directory cannot be deleted until ArcMap/ArcCatalog is closed.

There is code here that hints at a solution, but there are elements of that code that are missing.

    public Dictionary<Int32, Dictionary<Int32,Double>> GetTabulatedAreaDict()
    {
        IGPUtilities3 gpUtil = new GPUtilitiesClass();
        Geoprocessor gp = new Geoprocessor();

        //Tabulate Area
        string tableName = "lcAreaByRru.dbf";
        string tablePath = this.tempDirPath + "\\" + tableName;
        TabulateArea tabulateArea = new TabulateArea();
        tabulateArea.in_zone_data = this.rruPath;
        tabulateArea.zone_field = "VALUE";
        tabulateArea.in_class_data = this.rasterValue.GetAsText();
        tabulateArea.class_field = "VALUE";
        tabulateArea.out_table = tablePath;
        gp.Execute(tabulateArea, null);

        // Extract information from table
        IWorkspaceFactory wsf = new ShapefileWorkspaceFactoryClass();
        IWorkspace ws = wsf.OpenFromFile(this.tempDirPath, 0);
        IFeatureWorkspace fws = (IFeatureWorkspace)ws;
        ITable taTable = fws.OpenTable(tableName);// Creates .sr.lock file
        //ITable taTable = gpUtil.OpenTableFromString(tablePath); // Creates .sr.lock file
        ICursor tableRows = taTable.Search(null, false); // Creates .rd.lock file
        IRow tableRow = tableRows.NextRow();
        this.tabulatedAreaDict = new Dictionary<Int32, Dictionary<Int32, Double>>();
        while (tableRow != null)
        {
            Int32 id = (Int32)tableRow.get_Value(1); // Feature ID
            Dictionary<Int32, Double> valueAreaDict = new Dictionary<Int32, Double>();
            for (int i = 2; i < tableRow.Fields.FieldCount; i++)
            {
                int key = int.Parse(tableRow.Fields.get_Field(i).Name.Split('_')[1]);
                double value = (double)tableRow.get_Value(i);
                valueAreaDict.Add(key, value);
            }
            this.tabulatedAreaDict.Add(id, valueAreaDict);
            tableRow = tableRows.NextRow();
        }

        System.Runtime.InteropServices.Marshal.ReleaseComObject(tableRows); //Removes .rd.lock file
        System.Runtime.InteropServices.Marshal.ReleaseComObject(taTable); // Does not remove .sr.lock file

        return this.tabulatedAreaDict;
    }

Update:

I found that the dbf was not locked, but there were stray lock files associated with the dbf. While ArcCatalog was still running, I was able to delete the table, but I was not able to delete the folder containing the dbf. Deletion of the parent directory failed when using the ArcCatalog GUI or Windows Explorer. I was able to delete the folder using the Delete_management geoprocessing tool.

I had considered accessing the dbf using a non-ArcObjects method, but I realized I would probably run into this problem later with feature classes and geodatabases, so it was best to continue using ArcObjects.

To better manage this issue, I intend to create the table in the scratch workspace (system temp if unspecified) then move the file to the correct destination when I'm finished accessing it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘初心 2024-10-16 15:45:04

您发布的代码看起来与我通常所做的没有太大不同,但也许您可以尝试将工作区工厂和地理处理器拉到更全局的级别,而不是在每个方法调用时实例化它们。我确实记得使用地理处理器时遇到了一些锁定问题,因此我尽量避免使用它并尽可能直接使用 arcobjects。

您最好在 gis.stackexchange.com 上提出这个问题。据我所知,至少有一位 ArcObjects 专家经常光顾那个地方。

The code you posted doesn't look too different from what I usually do, but maybe you could try pulling the workspace factory and the geoprocessor to a more global level instead of instantiating them at every method call. I do remember running into some locking problems using the geoprocessor, so I try to avoid using it and working with arcobjects directly where possible.

You'll be better off asking this question at gis.stackexchange.com. I know of at least one ArcObjects guru frequenting that place.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文