国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#中的IDisposable模式

2019-11-14 16:27:44
字體:
供稿:網(wǎng)友

當(dāng)談到垃圾回收,在C#中,托管資源的垃圾回收是通過CLR的Garbage Collection來實(shí)現(xiàn)的,Garbage Collection會(huì)調(diào)用堆棧上對(duì)象的析構(gòu)函數(shù)完成對(duì)象的釋放工作;而對(duì)于一些非托管資源,比如數(shù)據(jù)庫鏈接對(duì)象等,需要實(shí)現(xiàn)IDisposable接口進(jìn)行手動(dòng)的垃圾回收。那么什么時(shí)候使用Idisposable接口,以及如何使用呢?

 

public interface IDisposable
{
    void Dispose();
}
public class DisposablClass : IDisposable
{
    //是否回收完畢
    bool _disposed;
    public void Dispose()
    {
        Dispose(true);
        GC.SupPRessFinalize(this);
    }
    ~DisposableClass()
    {
        Dispose(false);
    }
    
    //這里的參數(shù)表示示是否需要釋放那些實(shí)現(xiàn)IDisposable接口的托管對(duì)象
    protected virtual void Dispose(bool disposing)
    {
        if(_disposed) return; //如果已經(jīng)被回收,就中斷執(zhí)行
        if(disposing)
        {
            //TODO:釋放那些實(shí)現(xiàn)IDisposable接口的托管對(duì)象
        }
        //TODO:釋放非托管資源,設(shè)置對(duì)象為null
        _disposed = true;
    }
}

 

Dispose()方法

當(dāng)需要回收非托管資源的DisposableClass類,就調(diào)用Dispoase()方法。而這個(gè)方法不會(huì)被CLR自動(dòng)調(diào)用,需要手動(dòng)調(diào)用。

 

~DisposableClass(),析構(gòu)函數(shù)

當(dāng)托管堆上的對(duì)象沒有被其它對(duì)象引用,GC會(huì)在回收對(duì)象之前,調(diào)用對(duì)象的析構(gòu)函數(shù)。這里的~DisposableClass()析構(gòu)函數(shù)的意義在于告訴GC你可以回收我,Dispose(false)表示在GC回收的時(shí)候,就不需要手動(dòng)回收了。

 

虛方法Dispose(bool disposing)

通過此方法,所有的托管和非托管資源都能被回收。參數(shù)disposing表示是否需要釋放那些實(shí)現(xiàn)IDisposable接口的托管對(duì)象。

 

如果disposings設(shè)置為true,就表示DisposablClass類依賴某些實(shí)現(xiàn)了IDisposable接口的托管對(duì)象,可以通過這里的Dispose(bool disposing)方法調(diào)用這些托管對(duì)象的Dispose()方法進(jìn)行回收。

 

如果disposings設(shè)置為false,就表示DisposableClass類依賴某些沒有實(shí)現(xiàn)IDisposable的非托管資源,那就把這些非托管資源對(duì)象設(shè)置為null,等待GC調(diào)用DisposableClass類的析構(gòu)函數(shù),把這些非托管資源進(jìn)行回收。

 

另外,以上把Dispose(bool disposing)方法設(shè)置為protected virtual的原因是希望有子類可以一起參與到垃圾回收邏輯的設(shè)計(jì),而且還不會(huì)影響到基類。比如有這樣的一個(gè)子類:

public class SubDisposableClass : DiposableClass
{
    private bool _disposed; //表示是否已經(jīng)被回收
    protected override void Dispose(bool disposing)
    {
        if(!_disposed) //如果還沒有被回收
        {
            if(disposiing) //如果需要回收一些托管資源
            {
                //TODO:回收托管資源,調(diào)用IDisposable的Dispose()方法就可以
            }
            //TODO:回收非托管資源,把之設(shè)置為null,等待CLR調(diào)用析構(gòu)函數(shù)的時(shí)候回收
            _disposed = true;
        }
        base.Dispose(disposing);//再調(diào)用父類的垃圾回收邏輯
    }
}

 

在.NET 2.0之前,如果一個(gè)對(duì)象的析構(gòu)函數(shù)拋出異常,這個(gè)異常會(huì)被CLR忽略。但.NET 2.0以后,如果析構(gòu)函數(shù)拋出異常就會(huì)導(dǎo)致應(yīng)用程序的崩潰。所以,保證析構(gòu)函數(shù)不拋異常變得非常重要。


還有,Dispose()方法允許拋出異常嗎?答案是否定的。如果Dispose()方法有拋出異常的可能,那就需要使用try/catch來手動(dòng)捕獲。以下是考慮Dispose()方法有異常可能的寫法:

public class DisposableClass : IDisposable
{
    bool _disposed;
    ......
    protected virtual void Dispose(bool disposing)
    {
        if(_disposed) return;
        if(disposing)
        {
            //TODO:調(diào)用托管資源的Dispose()方法進(jìn)行垃圾回收
        }
        try
        {
            _channelFactory.Close(); //關(guān)閉的時(shí)候可能會(huì)有異常
        }
        catch(Exception ex)
        {
            _log.Warn(ex);//記錄日志
            try
            {
                _channelFactory.Abort();//丟棄的時(shí)候可能會(huì)有異常
            }
            catch(Exception cex)
            {
                _log.Warn(cex);//記錄日志
            }
        }
        _channelFactory = null;
        _disposed = true;
    }
}

 

總結(jié):當(dāng)我們自定義的類及其業(yè)務(wù)邏輯中引用某些托管和非托管資源,就需要實(shí)現(xiàn)IDisposable接口,實(shí)現(xiàn)對(duì)這些資源對(duì)象的垃圾回收。

 

參考資料:

http://m.survivalescaperooms.com/lori/p/3535470.html
http://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗田县| 宁陕县| 冀州市| 兴国县| 沈丘县| 南部县| 南召县| 扶余县| 沂水县| 中卫市| 贵定县| 隆尧县| 崇阳县| 嘉义市| 始兴县| 海口市| 鲁山县| 紫云| 思南县| 高平市| 申扎县| 龙口市| 金秀| 始兴县| 宕昌县| 宜宾县| 运城市| 乐清市| 华安县| 永新县| 高要市| 岗巴县| 永修县| 苍梧县| 襄汾县| 莱西市| 金川县| 顺义区| 大连市| 东宁县| 江口县|