Category: Öfkeli Coder
VB.Net Üzerine
May 27th, 2009Bu tarihlerden yaklaşık 8 yıl öncesinde Microsoft .Net adında bir platform çıkaracağını duyurduğunda üzerinde en çok durulan konulardan biriside o zamanlarda var olan VB projelerinin yeni platform'a fazla değişiklik yapmadan upgrade edilebileceğiydi.
Ufak tefek problemler dışında bu sözlerinde durdular da, şu anda Microsoft'u bulunduğu yere getiren VB'ye sadık kalarak şu anda da .Net içerisinde VB kullanabiliyoruz.
Ancak VB'ye ait hafıza yönetimi, object oriented gibi kronik problemlerden bazıları da .Net içerisine taşınmış oldu. VB 6 üzerinde çok fazla proje yapmış birisi olarak bu tür problemlerden uzak durabilmek için başından beri .Net içerisinde VB kullanmaya pek sıcak bakmadım.
Bu 8 yıl içinde IDE içerisindeki bana garip gelen özellikler dışında üretilen kod gibi çok fazla detayına girmedim ancak yakın bir arkadaşımın VB.Net üzerindeki projesinde memory problemleri çıktığı için detaylarla uğraşınca boşuna endişelenmediğim ortaya çıktı.
VB ile 5-6'dan fazla form olan bir proje üzerinde çalışıyor iseniz benzer sorunlar sizinde kapınızda olabilir.
Neler oluyor ?
Öncelikle VB syntax'ına çok alışık olmadığım için örnekleri c# ile veriyorum, umarım anlaşılır olur.
VB ile yeni bir proje açtığınızda projenizde görmediğiniz MyProject adında bir class tanımlanıyor ve bu class ile proje içerisindeki kaynaklara erişiyorsunuz. Tanımı aşağıdakine benzer halde;
Code:
internal sealed class MyProject | |
{ | |
internal static MyApplication Application { get; } | |
internal static MyComputer Computer { get; } | |
internal static MyForms Forms { get; } | |
internal static User User { get; } | |
internal static MyWebServices WebServices { get; } | |
} |
Bu class sayesinde geliştirme yaparken gerekecek kaynaklara erişim sağlanıyor. Proje içerisindeki tanımlanan formlara da Forms üzerinden ismi ile erişilebiliyor. Örneğin "Login" isimli bir form'unuz var ise MyProject.Forms.Login.Show() diyerek login penceresinin gözükmesini sağlıyorsunuz.
Ancak sorun şu ki MyForms class'ı projeyi derlediğinizde otomatik üretilen bir class ve Login penceresi için aşağıdaki kod üretiliyor.
Code:
internal sealed class MyForms | |
{ | |
public frmLogin m_frmLogin; | |
public frmLogin Login | |
{ | |
get | |
{ | |
this.m_frmLogin = Create__Instance__<frmLogin>(this.m_Login); | |
return this.m_frmLogin; | |
} | |
set | |
{ | |
if (value != this.m_frmLogin) | |
{ | |
if (value != null) | |
{ | |
throw new ArgumentException("Property can only be set to Nothing"); | |
} | |
this.Dispose__Instance__<frmLogin>(ref this.m_frmLogin); | |
} | |
} | |
} | |
} |
Bu koddan anlaşılacağı üzere de Login penceresine 1 kez erişildiğinde uygulama kapanıncaya kadar hafızada kalmak zorunda ve bu class üzerinde referans'ı taşındığı için garbage collector tarafından da toplanamıyor.
Bu yüzden uygulama belirli bir süre kullanıldıktan sonra hafıza kullanımı giderek artmaya başlıyor. Bu sorunu çözmek adına uğraşsamda otomatik üretilen bir kod olduğu için müdehale edemiyorsunuz.
Çözüm
Henüz uygulamış değilim ancak olası tek çözüm MyForms üzerinde m_frmLogin public olarak tanımlanmış, henüz erişim olup olmadığı konusunda fikrim yok ancak olası tek çözüm reflection ile MyForms'u taramak gibi gözüküyor.
Biraz hack tipi bir çözüm ancak null olmayan ve ekranda gözükmeyen tüm m_frmLogin tipi değişkenleri zorla dispose edecek bir kod eklemeyi düşünüyorum. Eğer sorunsuz olarak çalışırsa bu yazıyı güncelleyerek buraya eklerim.
Sonuç
VB.Net eski uygulamaların yeni platform'a taşınması için bir kapı idi ancak bu kapıyı artık kullanan kimse kalmadı, yeni başlayan ve ortalama ve altı ağırlıkta uygulama geliştirmek için hazırlanmış bir dil, özet olarak hızlı sonuç gerektirmeyen ciddi uygulamalar için kullanılmasını tavsiye etmiyorum.
Evet syntax'ı biraz daha karışık ama eski alışkanlıkları bırakıp yerine daha ortak kullanımı olan c temelli, yazdığınız kodun gözüktüğü gibi çalışacağını bildiğiniz .Net'in doğal dili c# ile geliştirme yapmanızı tavsiye ederim.