Двата ми цента за слаби препратки в .Net

GC е вещ в възстановяването на паметта, заета от управлявани обекти. Трябва обаче да предприемете допълнителни мерки, за да улесните събирането на боклука за подобрена производителност на вашите приложения.

Слаба препратка е тази, която се позовава на обект в паметта, като в същото време дава възможност на събирача на боклук да събира обекта или да възстановява паметта, заета от обекта, когато GC работи. Достъпният обект не е боклук, събран по време на изпълнение.

Можете да използвате слаби препратки за обекти, които консумират много памет. Използвайки слаби препратки за такива обекти, вие разрешавате тези обекти да се събират боклук, като същевременно позволявате тези обекти да бъдат пресъздадени по-късно, ако е необходимо. Така че, ако имате голям обект във вашето приложение, който бихте използвали по-рядко, можете да използвате слаба препратка към такива обекти, при условие че пресъздаването на такива обекти не е толкова скъпо.

Имайте предвид, че когато създавате слаба препратка към обект, IntPtr към GCHandle се съхранява вътрешно от създадената от вас слаба препратка. Времетраенето използва този GCHandle за управление на таблица, която съдържа слаби препратки към обекти. Ако даден обект вече е бил събран, стойността на IntPtr ще бъде IntPtr.Zero. Когато слабата препратка към обекта е финализирана, съответното вписване на слабата препратка към обекта в слабата референтна таблица се премахва. Ако слабата препратка към обекта е все още жива и извикате свойството Target на слабата препратка, връща се действителният обект, посочен от GCHandle на слабата препратка.

Създаването на слаба препратка към обект не увеличава времето на живот на обекта. Той позволява на събирача на боклук да възстанови паметта, заета от обекта, когато не съществуват силни препратки към този обект. Разликата между слаба и силна препратка към обект е, че докато първата все още позволява на събирача на боклук да възстанови паметта, заета от този обект, силната препратка към обект не позволява на събирача на боклук да възстанови паметта, заета от този обект, ако обектът е достъпен.

Програмиране на слаба справка в C #

За да създадете слаба препратка, ще трябва да се възползвате от класа System.WeakReference. След като създадете слаба препратка към обект, можете да използвате свойството Target на слабата препратка, която сте създали, за да проверите дали оригиналният обект е все още жив. Следният кодов фрагмент показва как можете да създадете слаба препратка към обект.

Rectangle rectangle = new Rectangle(15, 10);

var weakReference = new WeakReference(rectangle);

Можете да използвате свойството IsAlive, за да проверите дали слабата препратка към обекта е все още жива. Ето списък с кодове, който илюстрира това.

static void Main(string[] args)

        {

            Rectangle rectangle = new Rectangle(15, 10);

            var weakReference = new WeakReference(rectangle);

            rectangle = null;

            bool isAlive = weakReference.IsAlive;

            if(isAlive)

            Console.WriteLine("The object is still alive");

            Console.Read();

        }

Ако силната препратка към обекта вече не е налична, можете да използвате свойството Target на слабата препратка, за да използвате обекта, както е показано в кодовия фрагмент, даден по-долу.

bool isAlive = weakReference.IsAlive;

if(isAlive)

{

Rectangle rectangle = weakReference.Target as Rectangle;

//You can now use the rectangle object as usual

}

Кратко и дълголетни слаби препоръки

Слабите препратки могат да бъдат краткотрайни или дълготрайни. Основната разлика между късата и слабата препратка е, че докато в първия случай свойството Target на слабата препратка става нула, ако GC възстанови обекта, във втория случай дългата слаба препратка е жива дори след като GC стартира, т.е. преживява GC цикъл. Имайте предвид, че трябва внимателно да използвате дълги слаби препратки, тъй като състоянието на обекта не може да бъде прогнозирано след финализирането.

По същество трябва да използвате кратки слаби препратки, когато искате да използвате обект, който е в използваемо състояние. Напротив, дългата слаба препратка е добър избор, когато искате да използвате обекта, независимо от състоянието му. За да създадете дълга слаба препратка, трябва да предадете „true“ като втори параметър на претоварения конструктор на класа WeakReference, докато създавате слабата препратка. Следният кодов фрагмент илюстрира това.

Rectangle rectangle = new Rectangle(15, 10);

var weakReference = new WeakReference(rectangle, true);