C# 使用SuperMap控制項需要千萬注意的地方

來源:互聯網
上載者:User
 C# 使用SuperMap控制項需要千萬注意的地方
討論SuperMap前,我們衷心的希望微軟能夠改進記憶體回收行程,更加智能的協助開發人員釋放對象。
首先看下傳統的COM對象與.NET架構物件模型的建立與釋放的不同:
(1)、COM對象的客戶必須自己管理COM對象的生存期,而.NET對象的生存期由CLR(Common Language Runtime)來管理,即通過GC(Garbage Collection)機制自動回收。
(2)、COM對象的客戶通過指標引用COM對象,對象在記憶體中的位置是不變的,而.NET對象在記憶體中的駐留由.NET架構執行環境(execution environment)來管理,對象在記憶體中的位置是可變的,比如出於最佳化效能的考慮,同時會更新所有對對象的引用。這一點也是以CLR中不使用指標為前提的。
簡單的說.com客戶每次引用對象的時候,就調用
          IUnKnown->AddRef(),而每次釋放對象的時候,就調用
          IUnKnown->Release(),一旦引用計數達到零,就釋放執行個體。
如何在.NET中Release徹底釋放呢?非常幸運,在.net中允許程式員顯式地自己調用com的Release方法,這個方法叫做System.Runtime.InteropServices.Marshal.ReleaseComObject。

現在來說SuperMap,根本上講SuperMap的控制項在.NET中都是COM對象,這次我們討論的要點就是如何寫才能完全徹底的釋放COM對象。先來看段代碼:
private void axSuperMap1_Tracked(object sender, EventArgs e)
{
soDatasetVector _soDatasetVector = SuperWorkspace.Datasources[0].Datasets[0] as soDatasetVector;
soRecordset _soRecordset = _soDatasetVector.Query("1=2", true, null, "");
if (_soRecordset.AddNew(axSuperMap1.TrackedGeometry, null) == -1)
{
       MessageBox.Show("添加資料失敗");
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soRecordset);
_soRecordset = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soDatasetVector);
_soDatasetVector = null;
}
這段代碼看似相當的簡潔 風格很棒。但是實際上卻沒有釋放完全。
現在我們就來說標題上的“千萬千萬”的地方。
對於一些隱含返回的對象,也要這樣調用ReleaseComObject才能將其正確釋放,並保證其正常運作。
對於一些隱含返回的對象,也要這樣調用ReleaseComObject才能將其正確釋放,並保證其正常運作。
對於一些隱含返回的對象,也要這樣調用ReleaseComObject才能將其正確釋放,並保證其正常運作。
現在我們來看看上面這段代碼的釋放完全的寫法:
private void axSuperMap1_Tracked(object sender, EventArgs e)
{
soDataSources _soDataSources = SuperWorkspace.Datasources;
soDataSource _soDataSource = SuperWorkspace.Datasources[0];
soDatasets _soDatasets=_soDataSource.Datasets;
soDataset _Dataset = _soDatasets[0];
soDatasetVector _soDatasetVector = _Dataset as soDatasetVector;
soGeometry _soGeometry = axSuperMap1.TrackedGeometry;
soRecordset _soRecordset = _soDatasetVector.Query("1=2", true, null, "");
if (_soRecordset.AddNew(_soGeometry, null) == -1)
{
       MessageBox.Show("添加資料失敗");
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soGeometry);
_soGeometry = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soRecordset);
_soRecordset = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soDatasetVector);
_soDatasetVector = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_Dataset);
_Dataset = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soDatasets);
_soDatasets = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soDataSource);
_soDataSource = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(_soDataSources);
_soDataSources = null;
}

你沒看錯,其實我也很鬱悶。這樣寫的確很弱,很委瑣。
但是千萬記住,如果不想你寫的產品在你想不到的時候彈出“System.AccessViolationException: 嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞。”的錯誤,還是老實再老實的用這很弱的寫法吧。

轉載自http://www.gisbox.cn/thread-156-1-1.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.