最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介紹

 更新時(shí)間:2022年06月26日 08:43:34   作者:天方  
這篇文章介紹了.Net中的弱引用字典WeakDictionary和ConditionalWeakTable,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

有的時(shí)候,我們需要給某些數(shù)據(jù)添加一些附加信息,一種常用的做法是使用一個(gè)Dictionary在填充這些附加信息如:

    var data = new Data();
    var tag = new Tag();

    var dictionary = new Dictionary<Data, Tag>();
    dictionary[data] = tag;

這么做本身沒(méi)有什么問(wèn)題,但是卻又一個(gè)不小的隱患,那就是在dictionary中保存著了data和tag的引用。當(dāng)data不再使用的時(shí)候,需要將其從dictionary中移除,否則data和tag得不到釋放。我們可以用如下代碼說(shuō)明這個(gè)問(wèn)題:(注意,由于Debug模式有時(shí)會(huì)影響GC,本文代碼需行在Release模式下)

    class Tag
    {
        public Tag()
        {
            Console.WriteLine("Create Tag");
        }

        ~Tag()
        {
            Console.WriteLine("Release Tag");
        }
    }

    class Data
    {
        public Data()
        {
            Console.WriteLine("Create Data");
        }

        ~Data()
        {
            Console.WriteLine("Release Data");
        }
    }

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new Dictionary<Data, Tag>();
        dictionary[data] = tag;

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

從運(yùn)行結(jié)果中可以看出,只有創(chuàng)建的輸出,而沒(méi)有釋放的輸出。這個(gè)就屬于資源泄漏了。雖然可以通過(guò)手動(dòng)在dictionary中刪除data來(lái)實(shí)現(xiàn)資源的釋放,但是這樣就要求我們手動(dòng)管理對(duì)象的生命周期了,而這往往不是一個(gè)比較容易做到的事情。

究其原因,是由于dictionary中保持著強(qiáng)引用、導(dǎo)致GC不會(huì)對(duì)其進(jìn)行回收。找到了這個(gè)原因后,那就有相應(yīng)的對(duì)策了,那就是改用弱引用來(lái)建立關(guān)聯(lián),這樣數(shù)據(jù)就會(huì)被GC釋放了。這種觀念關(guān)系我們通常稱為弱字典——WeakDictionary。弱字典也是保存著Key和Value的鍵值對(duì),它滿足如下需求:

  • 字典中保存著Key的弱引用,即使不釋放Key值,也可以被GC回收。

  • 字典中保存的Value的強(qiáng)引用,Key沒(méi)有被GC回收前,Value不會(huì)被GC回收。

  • 當(dāng)Key被GC回收時(shí),關(guān)聯(lián)關(guān)系從字典中移除,Value也能被GC回收。

知道了需求后,接下來(lái)就可以對(duì)Dictionary進(jìn)行簡(jiǎn)單的封裝,將其改造成弱字典了。

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new Dictionary<WeakReference<Data>, Tag>();
        var key = new WeakReference<Data>(data);
        dictionary[key] = tag;

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

運(yùn)行這段代碼后,我們就會(huì)發(fā)現(xiàn),Data數(shù)據(jù)能釋放了,但是并不完善,具體體現(xiàn)在如下方面:

  • Tag保存的仍然是強(qiáng)引用,得不到釋放

  • Key數(shù)據(jù)并不是Data類型了,存在一個(gè)檢索的問(wèn)題,否則無(wú)法CRUD。

對(duì)于第一個(gè)問(wèn)題,可以通過(guò)一個(gè)Timer來(lái)定時(shí)清理已經(jīng)釋放了的Key來(lái)解決;對(duì)于第二個(gè)問(wèn)題,則需要在內(nèi)部通過(guò)key來(lái)建立Hash表來(lái)解決。具體的實(shí)現(xiàn)還有點(diǎn)麻煩,也會(huì)引入一些新的問(wèn)題,這里就不繼續(xù)列舉了。

之所以不繼續(xù)改造下去了,是因?yàn)檫@里我是在造重復(fù)輪子,.Net的BCL中本身就已經(jīng)提供了一個(gè)弱字典——ConditionalWeakTable,通過(guò)ConditionalWeakTable改造上述代碼如下:

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new ConditionalWeakTable<Data, Tag>();
        dictionary.Add(data, tag);

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

從運(yùn)行結(jié)果來(lái)看,GC結(jié)束后,Key和Value都被GC回收掉了(再次強(qiáng)調(diào),需要運(yùn)行在Release版本下)。

這個(gè)類放置在System.Runtime.CompilerServices下,也很少見(jiàn)到有書里面介紹到它。這里我就簡(jiǎn)單的介紹一下其接口吧:

    dictionary.Add(data, tag);    //添加    
    dictionary.TryGetValue(data, out tag);    //查詢
    dictionary.Remove(data);    //刪除

這三個(gè)是它比較常見(jiàn)的接口,另外還有兩個(gè)不大用的接口,這里就不多介紹了。

最后,簡(jiǎn)單的試了它的性能,基本上和Dictionary差不多,查詢效率還是非常高的,內(nèi)部應(yīng)該也是一個(gè)Hash表。

到此這篇關(guān)于.Net弱引用字典WeakDictionary和ConditionalWeakTable的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

宜都市| 乐业县| 隆昌县| 鹰潭市| 嘉义县| 明光市| 曲阜市| 广平县| 呼和浩特市| 怀远县| 泸州市| 平邑县| 桐柏县| 张家港市| 紫金县| 巴中市| 仁怀市| 安多县| 宁明县| 定远县| 宜川县| 信阳市| 静海县| 汝阳县| 吴桥县| 甘泉县| 玉屏| 加查县| 望都县| 信宜市| 广灵县| 庄河市| 防城港市| 九龙城区| 辰溪县| 灵武市| 黄大仙区| 西藏| 安达市| 梁平县| 石渠县|