Salı, Ocak 20, 2009

BufferedGraphicsContext cannot be disposed of because a buffer operation is currently in progress.

 System.InvalidOperationException: BufferedGraphicsContext cannot be disposed of because a buffer operation is currently in progress.
   at System.Drawing.BufferedGraphicsContext.Dispose(Boolean disposing)
   at System.Drawing.BufferedGraphicsContext.Dispose()
   at System.Drawing.BufferedGraphicsContext.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at System.Drawing.BufferedGraphicsContext.Allocate(IntPtr targetDC, Rectangle targetRectangle)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

bu hata beni yedi bitirdi... neyseki programı çalıştırır çalıştırmaz vermiyordu ki programı geliştirmeme mani olmuyordu.  ** yarım saatte bir veriyordu ** 

Allaha şükür bu hata 19-01-2009 itibariyle tarihe karıştı.

herşey GDIView diye bir programla tanışmamla başladı.  MSDN Forumlarında hatayla ilgili  yardım ararken  karşılaştığım bu program adeta hayatımı değiştirdi. :) bu hata yüzünden dil değişikliğine gidebileceğimi bile düşünür olmuştum. ( sebep : Bir çok kişi bu hatanın .Net Frameworkten kaynaklandığı fikrinde birleşiyordu. )

** gelelim hatanın çözümüne **
GDIView programını çalıştırınca bide ne göreyim. GDI nesneleri sürekli olarak artıyor. hiç bişey yapmasam bile saniyede 3-4 GDI nesnesinin arttığını gördüm.bu GDI nesneleri 9999 a vardığında hatayı veriyordu. neyseki program daha ayrıntılı birşekilde artan nesnelerin Font nesnesi olduğunu gösterebiliyordu. peki hiç bişey yapmasan bile çalışan yerler neresi olur? diye sorulan soruya ya Timerler veya controllerin Paint/Draw event/metod/aşırıyüklemeleri demiyecekmisiniz... Timer i sadece AutoSave için kullanıyordum ki bu da istersen ayarlanıyordu ve enaz 1 dk lik peryoda düşürebiliyordun ki bu olması mümkün değildi. 
Geriye bir seçenek kalıyordu. hemen 275.000 satır kodun içinden Paint/Draw metodlarını araştırmaya başladım. bide ne göreyim komut satırı olarak satın aldığımız controlün fontunu kendim oluşturduğum bir font ile değiştirmişim ama metodun sonunda nesneyi silmek adına bişey yapmamışım. ...  biraz kendi kendime ...... den sonra 
ama ben bir c# programcısıyım ve garbage collection a güveniyorum u sayıkladım... 
Aslında garbage collection native olarak eklenmiş olan kodları toplamayı garanti etmediğini, aslında hiçbirşeyi garanti etmediğini biliyordum.  neyse metodun sonuna 
DeleteObject( hFont );  kodunu dahil edince sanki üzerimden sekiz-dokuz ayın ağırlığı kalkmıştı. Artık patron proje yaparken yarım saatte bir yaptığı işi kaydedip programı yeniden başlatmayacak ve birgün bu salakça iş yüzünden vurulmayacaktım. 

vay beeaaa ne maceraymış..... 
neyse şu karara vardım : bu işi yapacaksam ya hiç cpp kodu eklemeyeceğim yada adam gibi cpp öğrenmeliyim... 

1 yorum:

cihandd dedi ki...

Selam Bayram,
Ben Cihan ormancı
ilginç bi yazı olmu
hatayı iyi bulmuşsun
tebrikler
valla bu açıklama belki başklarına da kaynak olur
kolay gelsin