AE开发中IFeatureClass中Search方法的笔记

最近有一个bug困扰了很久,找了半天终于发现了,现在做个总结,方便以后查阅。

在开发过程中,有一个问题就是IFeatureClass.Search()方法,这个方法中有两个参数。

public IFeatureCursor Search (
    IQueryFilter filter,
    bool Recycling
);

  第一个参数是查询条件,不多介绍,第二个参数是是否进行垃圾回收,对于这个参数的设置,有很多的学问。网上的查询教程一般都是设置为false。但是也有人提出设置为true的话会更快一些,在arcengine的开发帮助文档中也有提到。

The recycling parameter controls row object allocation behavior. Recycling cursors rehydrate a single feature object on each fetch and can be used to optimize read-only access, for example, when drawing. It is illegal to maintain a reference on a feature object returned by a recycling cursor across multiple calls to NextFeature on the cursor. Features returned by a recycling cursor should not be modified. Non-recycling cursors return a separate feature object on each fetch. The features returned by a non-recycling cursor may be modified and stored with polymorphic behavior.

可以看出,如果设置为true的话,每次IFeatureCursor.NextFeature()所拿到的IFeature就是同一个值,而false则是每次拿到的是其副本。这点很像值和引用之前的关系。下面给出例子。

        /// <summary>
        /// 按行来比较
        /// </summary>
        /// <returns></returns>
public IList<DiffRowWith2Dic> GetDiffFeatrRowFirst()
        {
            IList<DiffRowWith2Dic> diffRowList = new List<DiffRowWith2Dic>();
            IFeatureCursor baseFeatrCursor = _baseFeatrCls.Search(null, false);
       //
IFeatureCursor baseFeatrCursor = _baseFeatrCls.Search(null, true);
            IFeature baseFeatr = baseFeatrCursor.NextFeature();

            while (baseFeatr != null)
            {
                QueryConstructor queryConstrutor = new QueryConstructor();
                IQueryFilter queryFilter = queryConstrutor.CreateQueryFilter(baseFeatr);

                IFeatureCursor toCmprFeatrCursor = _toCmprFeatrCls.Search(queryFilter, false);
                IFeature toComprFeatr = toCmprFeatrCursor.NextFeature();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(toCmprFeatrCursor);
               
                if (toComprFeatr == null)
                {
                    baseFeatr = baseFeatrCursor.NextFeature();
                    continue;
                }
                foreach (string cmprFld in _cmprFldsList)
                {
                    if (!IsAttributeSame(baseFeatr, toComprFeatr, cmprFld))
                    {
                        DiffRowWith2Dic primeDiffRow = new DiffRowWith2Dic();

                        primeDiffRow.baseFeatr = baseFeatr;
                        primeDiffRow.baseStr = GetDataSetPath(_baseFeatrCls.FeatureDataset.Workspace.PathName);
                        primeDiffRow.toCmprFeatr = toComprFeatr;
                        primeDiffRow.toCmprStr = GetDataSetPath(_toCmprFeatrCls.FeatureDataset.Workspace.PathName);

                        diffRowList.Add(primeDiffRow);
                        break;
                    }
                }

                baseFeatr = baseFeatrCursor.NextFeature();
            }
            System.Runtime.InteropServices.Marshal.ReleaseComObject(baseFeatrCursor);
            //GC.Collect();

            return diffRowList;
        }

    /// <summary>
    /// 存储比较结果
    /// </summary>
    public struct DiffRowWith2Dic
    {
        public IFeature baseFeatr;
        public string baseStr;
        public IFeature toCmprFeatr;
        public string toCmprStr;
    }

  

在一开始,我的baseFeatrCursor是通过_baseFeatrCls.Search(null, true)来拿到的,然后发现每次我diffRowList中的baseFeatr都是一样的,其结果都是通过baseFeatrCursor.NextFeature()拿到的最新的baseFeatr,这个结果就很像是我拿到的只是baseFeatr的一个指针,而不是其中的对象。而toCmprFeatr不会出现上述问题,因为每次的toCmprFeatrCursor都是toCmprFeatrCls新Search()出来的结果,每次只用一次。

把_baseFeatrCls.Search(null, true)该为_baseFeatrCls.Search(null, false)问题就解决了。

 

posted @ 2014-01-21 09:39  chopic  阅读(1094)  评论(0编辑  收藏  举报