Skip to main content
1 of 4

i want to update about 700000 feature of a featureclass using arcengine & C#, but memory break

int nMax = (int)numFIDTo.Value; int nMin = (int)numFIDFrom.Value; IStepProgressor stepProg = ArcMap.Application.StatusBar.ProgressBar; stepProg.MinRange = 0; stepProg.MaxRange = nMax; stepProg.Position = 0; stepProg.Show(); try { IMap map = ArcMap.Document.ActiveView.FocusMap; IFeatureLayer flCrater = ClsShare.GetLayerFromName(map, comboBox1.Text) as IFeatureLayer;

            bool isPolygon = check_isPokygon.Checked;

            FrmAddField frmAddField = new FrmAddField(flCrater);
            int field_R = frmAddField.AddField("local_R", esriFieldType.esriFieldTypeDouble, true);

            

            IFeatureClass fcCrater = flCrater.FeatureClass;
            if (fcCrater == null)
            {
                MessageBox.Show("撞击坑图层要素为空!");
            }

            // 获取地理坐标系
            IGeoDataset geodataset = fcCrater as IGeoDataset;
            ISpatialReference spatialR_Crater = geodataset.SpatialReference;
            IGeographicCoordinateSystem geoSys = ClsShare.GetGeographicCoordinateSystem(spatialR_Crater);

            IFeatureCursor featureCursor = fcCrater.Update(null, false);
            IFeature feature = null;
            double dDiam = 0;
            double dR = 0;
            IClone polyClone;
            IPolyline polylineClone;
            while ((feature = featureCursor.NextFeature()) != null)
            {
                if (feature.OID < nMin || feature.OID > nMax)
                    continue;
                if (feature.ShapeCopy.IsEmpty) continue;
                // 将圆变成圆弧进行投影
                IPolygon polygonSrc = feature.ShapeCopy as IPolygon;
                IPolyline polylineSrc = new PolylineClass();
                polylineSrc.SpatialReference = polygonSrc.SpatialReference;
                ISegmentCollection segs = polylineSrc as ISegmentCollection;
                segs.AddSegmentCollection(polygonSrc as ISegmentCollection);
                IPoint ptCenter = ClsShare.GetCenter(polygonSrc as IGeometry);
                // 将中心点首先投影到地里坐标系上
                ptCenter.Project(geoSys);
                // 创建局部投影坐标系
                IProjectedCoordinateSystem prjLocal = ClsShare.CreateLocalProjectedCoordinateSystem(
                geoSys, 0, 0, 1.0, 0, ptCenter.X, ptCenter.Y);

                polyClone  = polylineSrc as IClone;
                polylineClone = polyClone.Clone() as IPolyline;
                polylineClone.Project(prjLocal);
                if (polylineClone.IsEmpty) continue;

                IGeometry geoPoly = polylineClone as IGeometry;

                //!<得到圆的外包最长边作为圆直径
                dDiam = 0.0;
                if (isPolygon)
                {
                    //!<如果是提取任意多边形的最长直径,则要取矩形框的对角线长度作为最长值
                    dDiam = Math.Sqrt(geoPoly.Envelope.Width * geoPoly.Envelope.Width + geoPoly.Envelope.Height * geoPoly.Envelope.Height);
                }
                else
                {
                    dDiam = Math.Max(geoPoly.Envelope.Width, geoPoly.Envelope.Height);
                }

                dR = dDiam / 2.0;
                feature.set_Value(field_R,dR);
                featureCursor.UpdateFeature(feature);
                stepProg.Step();

                System.Runtime.InteropServices.Marshal.ReleaseComObject(feature);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(polygonSrc);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(polylineSrc);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(ptCenter);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(prjLocal);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(segs);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(geoPoly);
            }
            stepProg.Hide();
            MessageBox.Show("撞击坑更新完成");
            System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
            System.GC.Collect();
            System.GC.WaitForPendingFinalizers();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message+"");
        }