您好,登錄后才能下訂單哦!
這篇文章主要介紹“C#中如何釋放非托管資源”,在日常操作中,相信很多人在C#中如何釋放非托管資源問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C#中如何釋放非托管資源”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
.NET 平臺在內(nèi)存管理方面提供了GC(Garbage Collection),負責自動釋放托管資源和內(nèi)存回收的工作,但它無法對非托管資源進行釋放,這時我們必須自己提供方法來釋放對象內(nèi)分配的非托管資源,比如你在對象的實現(xiàn)代碼中使用了一個COM對象
最簡單的辦法,可以通過實現(xiàn)protected void Finalize()(析構(gòu)函數(shù)會在編譯時變成這個東東)來釋放非托管資源,因為GC在釋放對象時會檢查該對象是否實現(xiàn)了 Finalize() 方法,如果是則調(diào)用它。但,據(jù)說這樣會降低效率……
有一種更好的,那就是通過實現(xiàn)一個接口顯式的提供給客戶調(diào)用端手工釋放對象的方法,而不是傻傻的等著GC來釋放我們的對象(何況效率又那么低)
System 命名空間內(nèi)有一個 IDisposable 接口,拿來做這事非常合適,就省得我們自己再聲明一個接口了
另外補充一句,這種實現(xiàn)并不一定要使用了非托管資源后才用,如果你設(shè)計的類會在運行時有大些的實例(象 GIS 中的Geometry),為了優(yōu)化程序性能,你也可以通過實現(xiàn)該接口讓客戶調(diào)用端在確認不需要這些對象時手工釋放它們
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example20 {
class Program {
class Class1 : IDisposable {
//析構(gòu)函數(shù),編譯后變成 protected void Finalize(),
GC會在回收對象前會調(diào)用調(diào)用該方法~Class1(){Dispose(false);
}
//通過實現(xiàn)該接口,客戶可以顯式地釋放對象,而不需要等待GC來釋放資源,
據(jù)說那樣會降低效率void IDisposable.Dispose(){Dispose(true);
}
//將釋放非托管資源設(shè)計成一個虛函數(shù),提供在繼承類中釋放基類的資源的能力
protected virtual void ReleaseUnmanageResources({
//Do something……
}
//私有函數(shù)用以釋放非托管資源private void Dispose(bool disposing){
ReleaseUnmanageResources();
//為true時表示是客戶顯式調(diào)用了釋放函數(shù),需通知GC不要再調(diào)用對象的Finalize方法
//為false時肯定是GC調(diào)用了對象的Finalize方法,
所以沒有必要再告訴GC你不要調(diào)用我的Finalize方法啦if (disposing{GC.SuppressFinalize(this);} static void Main(string[] args){
//tmpObj1沒有手工釋放資源,就等著GC來慢慢的釋放它吧Class1 tmpObj1 = new Class1();
//tmpObj2調(diào)用了Dispose方法,傳說比等著GC來釋放它效率要調(diào)一些
//個人認為是因為要逐個對象的查看其元數(shù)據(jù),以確認是否實現(xiàn)了Dispose方法吧
//當然最重要的是我們可以自己確定釋放的時間以節(jié)省內(nèi)存,優(yōu)化程序運行效率
Class1 tmpObj2 = new Class1()((IDisposable)tmpObj2)。Dispose();
}
C#學習經(jīng)驗之P/Invoke是什么?
在受控代碼與非受控代碼進行交互時會產(chǎn)生一個事務(wù)(transition) ,這通常發(fā)生在使用平臺調(diào)用服務(wù)(Platform Invocation Services),即P/Invoke
如調(diào)用系統(tǒng)的 API 或與 COM 對象打交道,通過 System.Runtime.InteropServices 命名空間,雖然使用 Interop 非常方便,但據(jù)估計每次調(diào)用事務(wù)都要執(zhí)行 10 到 40 條指令,算起來開銷也不少,所以我們要盡量少調(diào)用事務(wù),如果非用不可,建議本著一次調(diào)用執(zhí)行多個動作,而不是多次調(diào)用每次只執(zhí)行少量動作的原則。
C#學習經(jīng)驗之StringBuilder 和 String 的區(qū)別?
String 雖然是一個引用類型,但在賦值操作時會產(chǎn)生一個新的對象,而 StringBuilder 則不會,所以在大量字符串拼接或頻繁對某一字符串進行操作時***使用 StringBuilder,不要使用 String
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example22 {
class Program {
static void Main(string[] args){
const int cycle = 100000;
long vTickCount = Environment.TickCount;
String str = null;
for (int i = 0; i < cycle; i++)
str += i.ToString();
Console.WriteLine
("String: {0} MSEL", Environment.TickCount - vTickCount);
vTickCount = Environment.TickCount;
//看到這個變量名我就生氣,奇怪為什么大家都使它呢? :)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cycle; i++)
sb.Append(i);
Console.WriteLine
("StringBuilder: {0} MSEL", Environment.TickCount - vTickCount);
Console.ReadLine();
}
到此,關(guān)于“C#中如何釋放非托管資源”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。