日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C#實(shí)現(xiàn)IDisposable接口釋放非托管資源_C#教程

作者:Laggage's ? 更新時(shí)間: 2022-07-08 編程語(yǔ)言

Reference

Why using finalizers is a bad idea

當(dāng)在一個(gè)類(lèi)中使用了另外一個(gè)實(shí)現(xiàn)了IDisposable的類(lèi)作為一個(gè)成員屬性時(shí), 此時(shí)這個(gè)類(lèi)就有必要也去實(shí)現(xiàn)IDisposable接口, 以確保在合適的實(shí)際釋放非托管資源, 到底該如何正確的實(shí)現(xiàn)這個(gè)接口呢? 當(dāng)然這只是需要實(shí)現(xiàn)IDisposable接口其中一種情況

完整示例

示例的Foo類(lèi)中包含了一個(gè)Stream類(lèi)型的_stream成員, 因此需要為Foo類(lèi)實(shí)現(xiàn)IDisposable模式

public class Foo : IDisposable
{
    private bool _disposed;
    private readonly Stream? _stream;
    public Foo()
    {
        _stream = File.Create("1.txt", 2048);
    }
    ~Foo()
    {
        CleanupUnmanagedResources();
    }
    private void CleanupUnmanagedResources()
    {
        if (_disposed) return;
        // 釋放非托管資源
        _stream?.Dispose();
        _disposed = true;
    }
    public void Dispose()
    {
        CleanupUnmanagedResources();
        GC.SuppressFinalize(this);
    }
}

為什么要實(shí)現(xiàn)Foo析構(gòu)函數(shù)

因?yàn)槿诵缘娜觞c(diǎn)(??)

哈哈, 其實(shí)因?yàn)槲覀冊(cè)谑褂?code>Foo時(shí)可能會(huì)忘記手動(dòng)調(diào)用其Dispose方法, 這個(gè)時(shí)候如果沒(méi)有析構(gòu)函數(shù)的話(huà), 很可能導(dǎo)致資源永遠(yuǎn)得不到釋放最終釀成內(nèi)存泄漏的慘劇.

當(dāng)然啦, 在析構(gòu)函數(shù)中釋放非托管資源可能會(huì)給GC帶來(lái)額外的開(kāi)銷(xiāo), 所以最好的做法是依然是使用using塊保證能夠及時(shí)的調(diào)用Dispose方法, 這里使用析構(gòu)函數(shù)只是為了防止意外的發(fā)生. 至于為什么說(shuō)在析構(gòu)函數(shù)中釋放非托管資源會(huì)導(dǎo)致額外的GC開(kāi)銷(xiāo)呢, 這涉及到GC回收過(guò)程,GC在處理包含析構(gòu)函數(shù)的類(lèi)時(shí)不會(huì)立即將此類(lèi)回收, 而是會(huì)被GC標(biāo)記為下一代, 這樣這個(gè)被標(biāo)記為下一代的類(lèi)只有在GC決定回收下一代的垃圾對(duì)象時(shí), 才會(huì)被真正回收掉, 這樣一來(lái)就會(huì)導(dǎo)致額外的內(nèi)存和性能開(kāi)銷(xiāo)了.

Dispose方法中為什么要調(diào)用GC.SuppressFinalize

GC.SuppressFinalize方法可以告訴GC不需要在調(diào)用此類(lèi)的析構(gòu)函數(shù)(Finalizers)了;

因?yàn)樵?code>Foo類(lèi)的析構(gòu)函數(shù)中調(diào)用了Foo.CleanupUnmanagedResources方法, 當(dāng)GC回收此類(lèi)調(diào)用此類(lèi)析構(gòu)函數(shù)時(shí), 有可能會(huì)導(dǎo)致兩次調(diào)用Foo.CleanupUnmanagedResources(第一次是Dispose方法中調(diào)用的)導(dǎo)致額外的開(kāi)銷(xiāo),

所以當(dāng)我們手動(dòng)調(diào)用了Foo.Dispose(通過(guò)是通過(guò)using語(yǔ)法糖)后, 就需要告訴GC, "你回收我的時(shí)候用不著調(diào)用我的析構(gòu)函數(shù)了, 該釋放的資源我早就釋放掉了已經(jīng)", 轉(zhuǎn)換成代碼就是GC.SuppressFinalize

原文鏈接:https://www.cnblogs.com/laggage/p/15734776.html

欄目分類(lèi)
最近更新