Memik Yanık
- Kişisel Web Sitesi
Ana Sayfa
|
Hakkımda
|
Kitap Önerileri
|
Fotoğraflarım
|
RSS
|
İletişim
İçerik Kategorileri
»
Benden
»
Genel
»
Kitaplarım
»
Yazılım
Makale Kategorileri
»
ADO.NET
»
ASP.NET
»
C# 3.0 Kitabı
»
C#.NET
»
Delphi
»
Delphi Prism
»
Forumlardaki Sorular
»
Görsel Dersler
»
Güvenlik
»
Programcılık Dersleri
»
SQL Server
»
VB.NET
Arama
İçerikler
Makaleler
Tema
Mavi Tema
Sarı & Lacivert Tema
Kırmızı Tema
Mor Tema
Turuncu Tema
Siyah Tema
Yeşil Tema
Kaynaklar
»
CETURK
»
Ceviz.Net
»
csharpnedir.com
»
Kariyer Video
»
sanalkurs
»
Yazgeliştir
»
Yazılım Günlüğü
Takip Ettiklerim
»
Adem Aktepe
»
Aydın ÜNLÜ
»
Cengiz HAN
»
Cihan YAKAR
»
Fatih COŞKUN
»
Fatih Durgut
»
Fatih Tolga Ata
»
Görkem Sezgin
»
Gürcan Serbest
»
Gürkan Yeniçeri
»
Kod Yazıyorum
»
Levent Yıldız
»
Mahmut Kantar
»
Mehmet Güzel
»
Mehmet Nuri ÇANKAYA
»
Recip SELLİ
»
Sem Göksu
»
Tamer ÖZ
»
Tuğrul Helvacı
»
Uğur UMUTLUOĞLU
»
Yağız GÖNÜLER
»
Yasin Sirkecili
Arşiv
»
2010 Mayıs (1)
»
2010 Nisan (2)
»
2010 Ocak (1)
»
2009 Aralık (2)
»
2009 Kasım (14)
»
2009 Ekim (19)
»
2009 Eylül (3)
»
2009 Ağustos (3)
»
2009 Temmuz (12)
»
2009 Haziran (2)
»
2009 Mayıs (55)
»
2009 Nisan (26)
Form Sınıfının Dispose Metodu
Visual Studio ile hazırladığınız projeye yeni bir form eklediğinizde forma ait
Designer.cs
dosyasında aşağıdaki gibi bir
Dispose
() metodu hazırlanmaktadır. Başka bir deyişle
Form
sınıfı kaynaklı Dispose() metodu
override
edilmektedir. Aşağıda verilen kodu incelerseniz “Form1” için Visual Studio tarafından override edilen Dispose() metodunun geriye değer göndermediğini ve
bool
bir parametreye sahip olduğunu görürsünüz. Metotta ilk olarak “disposing” adlı bool parametrenin
true
olup olmadığı araştırılmaktadır.
disposing
adı verilen parametre true ise bu kez
IContainer
tipindeki
components
değişkenin
null
olup olmadığına bakılmaktadır.
Hem Dispose() metodunun parametresi true hem de
IContainer
tipindeki değişkenin içeriği null’dan farklı ise
Dispose
() metodunun parametresiz versiyonu
components
adlı IContainer tipindeki değişkene uygulanmaktadır. Tam bu noktada bazılarınızın aklına bu components adındaki ve IContainer tipindeki değişkenin işlevi nedir sorusu gelmiş olabilir.
Hatta Visual Studio ile hazırlanan projeleri didik didik etseniz bile bu
components
adındaki değişkenin hiç kullanılmadığını ve
null
olarak kaldığını görürsünüz. Bu nedenle birçok kaynakta “components” adlı bu değişkenden hiç söz edilmez. Aslında sizler de bu değişkenle ilgilenmeyebilirsiniz. Madem Microsoft’un programcıları
Override
ettikleri Dispose() metodu içinde bu değişkenin null olup olmadığını araştırıyorlar biraz üzerinde duralım. Bu amaçla üzerinde çalıştığım projenin formunun
Load
olayını temsil eden metodu aşağıdaki gibi düzenledim.
private void Form1_Load(object sender, EventArgs e)
{
TextBox Text1 = new TextBox();
Button Dugme1 = new Button();
}
.NET Framework ile gelen 2 sınıfın örneğinin alındığı bu metotta hazırlanıp formun
Controls
koleksiyonuna eklenmeyen bu 2 nesne Form1_Load() metodunun sonuna gelindiğinde her ikisi de gereksiz nesne durumuna düşerler. Bu şartlarda GC mekanizması uygun gördüğü bir zamanda bu 2 nesneyi bellekten temizler. Bu 2 nesne formun
Controls
koleksiyonuna eklenseydiler form kapatıldığında ikisi de otomatik olarak dispose edilirdi. Madem bu 2 nesneyi Controls koleksiyonuna eklemedik o halde form kapatıldığında bu nesnelerin otomatik olarak dispose edilmesini sağlayacak başka bir teknik olmalıdır.
Bu teknik
GC
sınıfının
Collect
() metodunu çağırmak olmadığına göre ve Controls koleksiyonuna eklenmeyen(tabi eklenemeyen nesneler de olabilir) çok sayıda nesne söz konusu ise hepsine tek tek Dispose() metodunu uygulamak mümkündür. Microsoft’un bu konudaki önerisi bütün bu nesneleri(yani Controls koleksiyonuna eklenmeyen..) bir
Container
’a eklemek ve hepsini birden formun override edilmiş
Dispose
() metodu içinde dispose etmektir.
Container’lar hakkında ayrıntılı bilgi vermesem bile Controls koleksiyonuna eklenmeyen nesnelerin nasıl toptan dispose edildiğini örnekleyeceğim. Madem Form1.Designer.cs dosyasında Container tipinde ve
components
adında bir değişken tanımlanmış yeni bir değişken tanımlamak yerine formun Load olayını temsil eden metotta
Container
nesnesi hazırlayıp components adı verilen bu değişkene aktaracağım. Bu amaçla yukarıda verdiğim Form1_Load() metodunu aşağıdaki gibi düzenledim.
private void Form1_Load(object sender, EventArgs e)
{
TextBox Text1 = new TextBox();
Button Dugme1 = new Button();
components = new Container();
components.Add(Text1);
components.Add(Dugme1);
}
Bu andan itibaren bu 2 nesne components adı verilen Container’ın üyesidir. Eğer bu Container nesnesine Dispose() metodu uygulanırsa bütün üyeleri dispose edilmiş olur ki bu işlem formun override edilmiş Dispose() metodunda yapılmaktadır. Aşağıda Form1.Designer.cs dosyasındaki Dispose() metodunu tekrar verdim.
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Madem bu formun Load olayını temsil eden metodunda Container nesnesi hazırlanıp components adında ve IContainer tipindeki değişkene aktarıldı, artık
if (disposing && (components != null))
karşılaştırması doğru değerini verir. Bu karşılaştırma true iken components adlı container nesnesi Dispose() metodu ile dispose edildiğine göre formun Controls koleksiyonuna eklenmeyen nesneler böyle bir yöntemle topluca dispose edilmiş olunuyor.
Bu şekilde formun Override edilmiş Dispose() metodundaki components adlı değişkenin sırrını çözdükten sonra artık
Form
sınıfı kaynaklı(aslında IComponent arabirimi kaynaklı) Dispose() metodu üzerinde biraz durabiliriz. Bu amaçla daha önce değişik kez bu kitapta kullanılan bir cümleyi buraya tekrar yazacağım:
Show() metodu ile ekrana getirilen formlar herhangi bir şekilde kapatıldıklarında Dispose edilmekte veya bellekten silinmektedir.
Tabii form kapatılmadan önce FormClosed ve FormClosing olaylarının meydana geldiğini biliyorsunuz. Bu nedenle formun FormClosed ve FormClosing olayları için aşağıdaki gibi 2 metot hazırlayıp sonra da çalışma anında formu ekrana getirip kapatmak isterseniz önce FormClosing olayıyla ilgili metot işletilir. Devamında FormClosed olayını temsil eden metot işletilir.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
MessageBox.Show("Form1'le ilgili FormClosing olayı meydana geldi");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
MessageBox.Show("Form1'le ilgili FormClosed olayı meydana geldi");
}
Kapatılmak istenen formla ilgili olarak bu 2 olay meydana geldikten sonra sıra formun Dispose metodunun işletilmesine gelir. Bu 2 olaydan sonra sıranın Dispose() metodunun işletilmesine geldiğini görmek istiyorsanız Form1.Designer.cs dosyasında override edilen Dispose() metodunu aşağıdaki gibi düzenleyebilirsiniz.
protected
override
void
Dispose(
bool
disposing)
{
System.Windows.Forms.MessageBox
.Show("Form1'in Dispose metodu işletildi"
);
if
(disposing && (components !=
null
))
{
components.Dispose();
}
base.Dispose(disposing);
}
Sanırım çalışma anında bir form kapatılmak istendiğinde geri planda meydana gelen olayların ve yapılan işlemlerin sıralaması anlaşıldı. Şimdi gelin Form1.Designer.cs dosyasındaki yani Visual Studio tarafından override edilmiş Dispose() metodunu silelim. Tabi üzerinde çalıştığımız proje deneysel amaçlı ve yukarıda sözü edilen “components” adlı IContainer tipindeki nesneye henüz herhangi bir nesne üye yapılmadığı için Visual Studio tarafından hazırlanan override edilmiş Dispose() metodunu silmek bir soruna neden olmaz. Çünkü form kapatılmak istendiğinde
Form
sınıfının Dispose() metodunun orijinal hali zaten işletilir. Bu tespitleri yaptıktan sonra Form1.cs dosyasında Form1’in
Form
sınıfı kaynaklı Dispose() metodunu kendim override ettim. Aslında orijinal haline MessageBox sınıfının Show() metodu ile mesaj veren bir satır eklemekle yetindim.
protected override void Dispose(bool disposing)
{
MessageBox.Show("Form1'in Dispose metodu işletildi");
base.Dispose(disposing);
}
M
essageBox
.Show() satırı hariç bu hali ile Dispose() metodunu override etmenin herhangi bir işlevi yoktur. Çünkü orijinali ile aynıdır. Şimdi bu metottaki
base.Dispose(disposing);
satırını silip ondan sonra projeyi çalıştırıp formu kapatmayı bir deneyin. Tahmin edeceğiniz gibi bu satır silindikten sonra formu bilinen yöntemlerle kapatmak mümkün olmaz. Çünkü Windows’tan gelen
Kapat
mesajını engellemiş oldum. Bu şartlarda forma bir düğme yerleştirip Dispose() metodunu aşağıdaki gibi kendiniz işletirseniz formu kapatmış olursunuz.
private void Kapat_Click(object sender, EventArgs e)
{
base.Dispose(true);
}
Tabi bu şartlarda formun FormClosing ve FormClosed olaylarını temsil eden metotlar işletilme şansı bulamazlar. Sanırım konu biraz aydınlandı. Tekrar etmek gerekirse;
Show
() metodu ile ekrana getirilen ve formların
Controls
koleksiyonlarına eklenen nesneler otomatik olarak Dispose edildikleri için bunları sorun yapmayabiliriz.
C#.NET
30.05.2009 02:51:58
YORUM YOK
Yorumlar
Yorum Yaz
Bu yazıya ilk yorum yapan siz olun.
Ad Soyad
E-Posta
Yorumunuz
Ana Sayfa
|
Hakkımda
|
Kitap Önerileri
|
Fotoğraflarım
|
RSS
|
İletişim
Memik Yanık 2004-2009 © Tüm Hakları Saklıdır.
Hazırlayan
www.semgoksu.com