Кога трябва да използвам dispose() върху графики?

Уча се да рисувам неща в C# и продължавам да виждам препоръки за използване на dispose(), но не разбирам напълно какво прави.

  • Кога трябва да използвам dispose() върху начертана с код графика?
  • Какво ще стане, ако не го направя?
  • Трябва ли да го извиквам всеки път, когато графика не се вижда, като например в GUI, който има раздели и потребителят е превключил към другия раздел, и след това да го преначертая, когато превключи обратно?
  • Ще счупя ли неща, ако го извикам, когато не трябва?
  • Ще избяга ли Батман от злите лапи на Жокера?

person lala    schedule 03.07.2010    source източник


Отговори (4)


  • Кога трябва да използвам dispose() върху изчертана с код графика? Всеки път, когато сте напълно готови с който и да е обект, който имплементира IDisposable, трябва да извикате Dispose точно преди да стане подходящ за събиране на отпадъци. Както посочиха други, най-добре е да използвате оператора using, вместо да извиквате директно Dispose.
  • Какво ще се случи, ако не го направя? Вашата програма ще бъде малко по-малко ефективна, защото ще заема малко повече ресурси от необходимото. Това е единственият недостатък да не се изхвърлят графики; обаче, неизхвърлянето на други класове всъщност може да причини грешки (един известен пример е StreamWriter). Поради тази причина е най-добре винаги да изхвърляте всеки клас, който имплементира IDisposable, като общо правило.
  • Трябва ли да го извиквам всеки път, когато графика не се вижда, като например в GUI, който има раздели и потребителят е превключил към другия раздел, и след това да го преначертавам, когато превключи обратно? Не. Обекти трябва да се изхвърлят само когато приключите напълно с тях.
  • Ще счупя ли неща, ако го извикам, когато не трябва? Да. Ако извикате Dispose, преди да сте готови с обекта, и след това опитате да използвате изхвърления обект, ще получите ObjectDisposedException.
  • Ще се измъкне ли Батман от злите лапи на Жокера? Включете се утре, в същото време на прилеп, същия канал на прилеп!
person Stephen Cleary    schedule 03.07.2010
comment
Това изисква още едно правило: не изхвърляйте обект, който не сте създали. Изхвърлянето на e.Graphics е неприятна латентна грешка. - person Hans Passant; 03.07.2010
comment
Само бележка за Graphics конкретно, ако е бил изхвърлен, извикването на неговите Draw... методи ще даде InvalidArgumentException със съобщението „параметърът е невалиден“ - не ObjectDisposedException. - person reve_etrange; 19.02.2015

Когато поискате графичен обект, Windows ще разпредели малко памет за вас. Извикването на dispose ще подреди тази памет за вас. Ако не извикате dispose, всички тези манипулатори на паметта ще останат отворени и в крайна сметка системата ви ще изчерпи ресурсите си, ще стане по-бавна и в крайна сметка ще спре (затварянето на програмата обаче може да ги освободи).

Тъй като използвате .NET, когато приключите с използването на вашия графичен обект, събирачът на отпадъци в крайна сметка ще извика dispose вместо вас. Проблемът със събирача на отпадъци е, че никога не знаете кога ще почисти обекта, така че може да остави тези ресурси отворени за по-дълго от необходимото.

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

using(Graphics g)
{
    // do something with the resource
}

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

person DanDan    schedule 03.07.2010

На езика на noob, Dispose() е за почистване, след като сте приключили с използването на неуправляван ресурс.

Какво е неуправляван ресурс? Това са всички неща, които CLR не управлява вместо вас. Те са нещо като манипулатори на файлове, връзки към бази данни, мрежови гнезда, GDI+ писалки и т.н. Получавате достъп до тези неща чрез типичен .NET обект, но той ще имплементира IDisposable, за да ви позволи да почиствате правилно.

Защо да почиствате? Докато не почистите след себе си, този ресурс не е достъпен за използване от други части на програмата. В това отношение вие ​​разбивате нещата, защото отнемате ресурс.

Защо да правите това сами? Трябва да направите това сами веднага щом престанете да се нуждаете от ресурса, вместо да разчитате на автоматичната магия на събирача на боклука, защото може да отнеме много време (добре, неуточнено) количество време, преди събирачът на боклук да стигне до него. Докато даден обект не бъде изхвърлен правилно, не можете да използвате повторно основния ресурс, така че програмата ви няма да функционира надеждно.

person Frederik    schedule 03.07.2010

Мич Уит казва - Винаги извиквайте Dispose() на всеки обект, който имплементира за еднократна употреба. GDI манипулаторите, използвани от графични обекти, не се управляват и изискват изхвърляне, когато приключите с тях.

person kv-prajapati    schedule 03.07.2010