标签:
1、问题描述最近在写C#下AE的开发,在循环获取数据并修改时碰到了两个问题“超出系统资源”和“超出打开游标最大数”;在网上看了一些资料,,发现都是说在循环中没有释放已经使用过的对象,但是在循环中实际上是有为com对象赋值为null的,但是还是没法解决。后来想着将对象赋值为null和marshal是不是效果不一样,就特意写了一个简单的循环来测试,代码如下(初级代码,比较乱,请轻喷):
1 public void Test_释放游标方式()
2
{
3
string ssName = "controlpoint";//图层名称(里面有4w多条数据)
//测试两种释放方式的执行时间
4
DateTime tmStart = DateTime.Now;
5
DisplayString("开始于:"+tmStart.ToLongTimeString()+"\r\n");
6
DateTime tmEnd;
7
DateTime tmMiddle1;
8
DateTime tmMiddle2;
9
TimeSpan ts, tsMax;
//具体执行代码
10
IFeatureWorkspace pFeaWs = mc_Ws as IFeatureWorkspace;//我已经建立好的SDE工作空间对象
11
IFeatureClass pFeaCls = pFeaWs.OpenFeatureClass(ssName);
12
string strWhere = string.Format("stationserieseventid in (‘f9bd16ed-ae2a-454c-9eba-7123dc41af28‘,‘7e3d0d4a-8c5e-49b5-8977-e060cd4cef6d‘,‘a89300a5-3503-4976-b5d2-3d5a712f7b36‘)");
13
IFeatureCursor pCur = null;
14
IFeature pFea = null;
15
IQueryFilter pFilter = new QueryFilterClass();
16
int numCurHasBuild = 0;
17
//int counsts = pFeaCls.FeatureCount(null);//总要素个数
18
try
19
{
20
tmStart = DateTime.Now;
21
DisplayString("开始于:" + tmStart.ToLongTimeString()+"\r\n");
22
tsMax = TimeSpan.MinValue;
23
int idxStart = 45809;
24
int idxEnd = 90416;
25
int idxTmpNode = idxStart + 1000
26
for (int idx = idxStart; idx < idxTmpNode; idx++)
27
{
28
tmMiddle1 = DateTime.Now;
29
strWhere = "objectid = ‘" + idx.ToString() + "‘";
30
pFilter.WhereClause = strWhere;
//获取游标对象
31
pCur = pFeaCls.Search(pFilter, false);//如果游标对象没有释放,那么一次循环不能超过280,否则会爆‘超出打开游标最大数’错误
32
numCurHasBuild++;
//循环获取游标内的要素
33
pFea = pCur.NextFeature();
34
while (pFea != null)
35
{
36
string tmp = pFea.get_Value(1).ToString();
37
pFea = pCur.NextFeature();
38
}
39
//pCur = null;//像这样,对象实际上是没有释放的;依旧会在283条的时候报错
40
Marshal.ReleaseComObject(pCur);//这种方式可以完全释放掉对象,此时可以完全循环完4w条数据
41
localReleaseComObj(pCur);
42
if (pCur != null)
43
localReleaseComObj(pCur);
45
tmMiddle2 = DateTime.Now;
46
ts = tmMiddle2 - tmMiddle1;
47
if (ts > tsMax)
48
tsMax = ts;
49
}
50
tmEnd = DateTime.Now;
51
DisplayString("循环中耗时最多的一次时间为:"+tsMax.TotalSeconds+"\r\n");
52
DisplayString("执行完一轮循环;消耗的总时间为:"+(tmEnd-tmStart).TotalSeconds+"\r\n");
53
}
54
catch (Exception ex)
55
{
56
DisplayString("在第" + numCurHasBuild.ToString() + "处发生错误!\r\n" + ex.Message);
57
throw new Exception(ex.Message);
58
}
59
}
在测试中,专门打开一个控制点图层(里面有4w多条数据),然后根据条件循环建立游标获取对象;
情况一:在使用完游标之后,将其赋值为null;这时候对象实际上是没有被释放掉的,因此在283次循环时就会报错‘ora 超出打开游标最大数’;
情况二:在使用完游标时,在循环末尾,用marshal.releasecomobject方法来释放com对象,这时循环可以走完4w次;我认为这时对象是完全被释放掉了的。
同时在使用marshal.releasecomobject方法时,并没有增加多余的时间,循环执行时间上还是跟不释放对象一样(小数据量比较)。
3、结论