前段時間,在.net中使用Supermap組件(activeX)時,發現經常出現記憶體不能寫的異常,後來與超圖公司聯絡,說是需要在代碼中釋放Com對象才可以。
今天在使用MapX組件時,又發現一個比較奇怪的問題:在處理拓樸關係時,處理部分資料後,出現NullReferenceException異常。代碼如下所示:
for (int i=1;i<=axMap1.Layers[LayerName].AllFeatures.Count;i++)
{
MapXLib.Feature ft=axMap1.Layers[LayerName].AllFeatures[i];
x1 = ft.Parts[1].get_X(1) ;
y1 = ft.Parts[1].get_Y(1);
ProcessData(x1,y1);
}
查了半天,也沒有找到原因所在,後來想到可能與Com對象的釋放有關,於是將代碼調整為:
MapXLib.Layer lay=axMap1.Layers[LayerName];
MapXLib.Features fs= lay.AllFeatures;
int c=fs.Count;
for (int i=1;i<=c;i++)
{
MapXLib.Feature ft=fs._Item(i);
MapXLib.Parts pts=ft.Parts;
MapXLib.Points pss=pts [1];
x1 = pss.get_X(1) ;
y1 = pss.get_Y(1);
ProcessData(x1,y1);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pss);
pss=null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(pts);
pts=null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(ft);
ft=null;
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(fs);
fs=null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(lay);
lay=null;
調整後的代碼運行正常。
在調整期間發現幾個值得注意的地方:
1、只要是定義了Com對象,在使用完之後必須釋放,否則,多次調用後,將出現問題。
2、中間臨時變數也需要釋放,如將
x1 = ft.Parts[1].get_X(1) ;
折為
MapXLib.Parts pts=ft.Parts;
MapXLib.Points pss=pts [1];
x1 = pss.get_X(1) ;
y1 = pss.get_Y(1);
再釋放變數。
3、如果某方法返回了Com對象,則需要定義返回的變數,然後將其釋放。
另外,發現使用FireFox瀏覽器時,部落格圓的瀏覽和編輯blog就存在一些問題了。