ArcMap扩展创建包含太多列的Shapefile会导致内存错误

时间:2013-11-25 17:41:50

标签: c# arcgis shapefile arcmap

我正在VS2012 C#中创建ESRI ArcMap 10.2扩展。我一直遇到一个问题,当我创建一个包含大量列的shapefile时,我得到错误:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

在功能工作区上实际运行“创建要素”方法时。以下是代码摘录:

public bool LoadData(DataQueryResult QueryResult, string ColumnX, string ColumnY)
{
    bool loaded = true;
    DataTable Data = QueryResult.ResultsTable;

    try
    {
        using (ESRI.ArcGIS.ADF.ComReleaser ComReleaser = new ESRI.ArcGIS.ADF.ComReleaser())
        {
            //Create the field collection for editing
            IFields Fields = new FieldsClass();
            ComReleaser.ManageLifetime(Fields);
            IFieldsEdit FieldsEdit = (IFieldsEdit)Fields;

            //Create the geometry field
            IGeometryDef GeomDef = new GeometryDef();
            IGeometryDefEdit GeomDefEdit = (IGeometryDefEdit)GeomDef;
            GeomDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;

            IField GeomField = new FieldClass();
            IFieldEdit GeomFieldEdit = (IFieldEdit)GeomField;
            GeomFieldEdit.Name_2 = ShapeFieldName;
            GeomFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
            GeomFieldEdit.GeometryDef_2 = GeomDef;
            GeomDefEdit.SpatialReference_2 = new UnknownCoordinateSystemClass();;

            FieldsEdit.AddField(GeomField);

            //Create the OID filed
            IField OidField = new FieldClass();
            IFieldEdit OidFieldEdit = (IFieldEdit)OidField;
            OidFieldEdit.Name_2 = "OID";
            OidFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
            FieldsEdit.AddField(OidField);

            //Add a field for each column
            foreach (DataColumn col in Data.Columns)
            {
                IField2 field = new FieldClass();
                IFieldEdit fieldedit = (IFieldEdit)field;
                fieldedit.Name_2 = col.ColumnName;
                bool AddField = false;

                if (col.DataType.IsIn(typeof(Int64), typeof(Int32)))
                {
                    //Best we can do is 32 bit in a shapefile
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    AddField = true;
                }
                else if (col.DataType == typeof(Int16))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
                    AddField = true;
                }
                else if (col.DataType == typeof(Single))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeSingle;
                    AddField = true;
                }
                else if (col.DataType == typeof(double))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeDouble;
                    AddField = true;
                }
                else if (col.DataType == typeof(string))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeString;
                    //Here is where I get "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." 
                    //The higher the number of fields the fewer "runs" of this method needed to hit the error.
                    //At 150 it is hit right away but if it is at, say, 50 it can run many times.
                    if (Fields.FieldCount < 150) 
                        AddField = true;
                    else
                        System.Diagnostics.Debug.Write(field.Name + "; ");
                }
                else if (col.DataType == typeof(DateTime))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeDate;
                    AddField = true;
                }
                else if (col.DataType == typeof(bool))
                {
                    fieldedit.Type_2 = esriFieldType.esriFieldTypeString;
                    AddField = true;
                }

                if (AddField)
                    FieldsEdit.AddField(field);

            }

            //FilePath is the ArcMap temp folder generated for the session so something like "C:\Users\USERNAME\AppData\Local\Temp\arc1097\\"
            IWorkspaceFactory WorkspaceFactory = new ShapefileWorkspaceFactoryClass();
            IFeatureWorkspace FeatureWorkspace = (IFeatureWorkspace)WorkspaceFactory.OpenFromFile(FilePath, hWnd);
            ComReleaser.ManageLifetime(WorkspaceFactory);

            //FileName is a class memeber which might be something like "o2zkdrnv.shp" which is randomly generated
            FeatureClass = FeatureWorkspace.CreateFeatureClass(FileName, Fields, null, null, esriFeatureType.esriFTSimple, ShapeFieldName, "");  //<-- THE ERROR OCCURS HERE
            ComReleaser.ManageLifetime(FeatureClass);
        }
    }
}

所以我只能假设它是某种内存错误。我允许的列越多(“&lt; 150”这一行),在遇到错误之前我可以重复运行的次数很少。似乎65左右是我立即开始看到它的门槛。在那之下,我可以运行它,比如,在击中它之前5-6次,但这似乎非常不一致。如果我停止调试VS并重新启动项目,似乎很快就会发生。我添加了ComReleaser认为它可能会有所帮助(甚至认为它在技术上不是ArcMap命名空间的一部分)但它没有任何区别。

传递的数据表包含以下字段列表:

RecordID,SiteID,SiteName,SiteType,LocID,LocName,LocType,LocX,LocY,LocZ,LocLong,LocLat,LocTop,LocBot,LocGroup,SampID,SampName,SampDate,SampDate2,SampTime,SampTime2,SampType,SampGroup,SampMatrix,SampTop,cSampTop,SampBot,cSampBot,SampElev,cSampElev,SampUnit,AnalyteID,Analyte,Result,cResult,Flag,Unit,DetectLim,cDetectLim,IsDetect,IsTIC,IsReject,Method,Category,LabID,Comment,Source,RegName01,RegValue01,RegAbove01,RegName02,RegValue02,RegAbove02,RegName03,RegValue03,RegAbove03,RegName04,RegValue04,RegAbove04,RegName05,RegValue05,RegAbove05,RegName06,RegValue06,RegAbove06,RegName07,RegValue07,RegAbove07,RegName08,RegValue08,RegAbove08,RegName09,RegValue09,RegAbove09,RegName10,RegValue10,RegAbove10,RegName11,RegValue11,RegAbove11,RegName12,RegValue12,RegAbove12,RegName13,RegValue13,RegAbove13,RegName14,RegValue14,RegAbove14,RegName15,RegValue15,RegAbove15,RegName16,RegValue16,RegAbove16,RegName17,RegValue17,RegAbove17,RegName18,RegValue18,RegAbove18,RegName19,RegValue19,RegAbove19,RegName20,RegValue20,RegAbove20,RegName21,RegValue21,RegAbove21,RegName22,RegValue22,RegAbove22,RegName23,RegValue23,RegAbove23,RegName24,RegValue24,RegAbove24,RegName25,RegValue25,RegAbove25,RegName26,RegValue26,RegAbove26,RegName27,RegValue27,RegAbove27,RegName28,RegValue28,RegAbove28,RegName29,RegValue29,RegAbove29,RegName30,RegValue30,RegAbove30

理论上,表的内容应该无关紧要,因为此方法从中获取的唯一内容是Columns集合。

非常感谢任何帮助。

0 个答案:

没有答案