2012-08-16 23 views
5

Bir Label oluşturmak ve bazen .DrawToBitmap() kullanıyorum. Nedenini bilmiyorum, ama ben bir süre benim programını çalıştıran (ve genellikle .DrawToBitmap() çağırarak) sonra özel durum almak: sık sıkDrawToBitmap - System.ArgumentException: Parametre geçerli değil

System.ArgumentException: Parameter is not valid. 
    at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format) 
    at System.Drawing.Bitmap..ctor(Int32 width, Int32 height) 

nasılsa diyemem bu fonksiyonu. Bunu radikal bir şekilde deneyeceksem: Bu özel durum 5-6 saniye sonra (1000-2000 aramalar) aldım. Sorun nedir? Bundan nasıl kurtuluruz?

Düzenleme: Dispose() ile bir fikriniz için teşekkür ederiz - her nasılsa label üzerinde kullanırsanız her şey mükemmel çalışıyor. Bitmap'te kullanmamam iyi olsa bile. Her iki cevap da harika, sadece 1 tane kabul edebilirim :(

cevap

6

Yani, bu hata mesajı GDI + 'dan aşağı doğru geliyor ve nedenleri için görülebilir. Kodunuzda bir göze çarpan sorun var. o ancak bir aday.:.

label.Font = new Font("Arial", 20); 

Font nesneler IDisposable uygulamak ve Dispose() çağıran sıkı bir döngü içinde bunlar bir sürü oluşturma ve asla aynı Bitmap kendisi için de geçerli GDI bitiyor bahis olur Kaynaklar

It's har d kodunuzu olduğu gibi anlamlandırır. Aslında kesinlikle hiçbir şey yapmaz ama bir ton Font ve Bitmap nesneler yaratır, bu yüzden bu bildirimlerin her birini bir using bildirimi içinde sarmayı öneremem. Bir kenara, bir GDI nesnesini hızlı bir şekilde ardı ardına atmadan oluşturduğunuzda, sonunda bu problemle karşılaşacaksınız.

Bu nesnelerin bir süredir geçerli olması gerekiyorsa, daha sonra yerel kaynakların mümkün olduğunca hızlı bir şekilde serbest bırakılması için bunlara Dispose() numaralı telefonu aradığınızdan emin olmanız gerekir (sonlandırıcı bunu sizin için yapacak, ancak en iyisi bunu beklememek için). yerel nesneler daha sonra bu yüzden Dispose() blok çıkışları çağrılacak bir using açıklamada sarılmasıdır ise:

using(var b = new Bitmap(w, h)) 
{ 
    // use 'b' for whatever 
} // b.Dispose() is called for you 
+0

Hi. İlk başta (Bitmap ...) => hiç değiştirmeyi denedim. Ama her aramanın sonunda label.Dispose() kullandığımda her şey iyiydi :) Teşekkür ederim - 30.000 arama ile test ettim, şu anda iyi düşünüyorum. Label.Dispose() olmadan 1000-2000 aramadan sonra istisna alırsınız. Etiketi atmam gerektiğini asla düşünmedim. – miri

+0

@miri: Like @HansPassant: Etiketin imha edilmesinin istisnaya yol açacağını düşünürdüm. 'Using' bloklarına sarılması gereken Font ve Bitmap olduğuna inanıyorum. Etiketin nasıl kullanıldığını görmeden etiketin imha edilmesini nasıl sağlayabileceğinizi bilmiyorum. – IAbstract

4

GDI + istisnalar oldukça fakir, genellikle de gerçek sorunu tarif yoktur. Bu durumda gerçekten "bitmap çok büyük" anlamına gelir. Hala iyi tarif etmiyorsa, aslında yönetilmeyen hafızanız tükeniyor. Bitmap, hala kullanılabilir bellek miktarına sığmayacak kadar büyük.

Bitmap'te Dispose() yöntemini çağırmıyorsunuz. Sıkıntıyı fark etmeden sık sık bu konuda kaygılanabilirsiniz. Ama Bitmap ile değil, toplanan hafızada çok az çöp toplayan ama çok fazla yönetilmeyen hafıza alan bir sınıf. Çöp toplayıcısını, finalleştiricinin yönetilmeyen belleği serbest bırakmasına izin verecek kadar hızlı tetiklemez.

kod parçacığı mantıklı değil ama bu istisna önlemek gibi yazacağınız:

using (Bitmap image = new Bitmap(300, 500)) { 
    label.DrawToBitmap(image, label.ClientRectangle); 
} 
+1

Ciddiyim, * Ciddi * GDI hata mesajlarından nefret ediyorum ... sadece sorunu teşhis etmek için deneyim gerektirir, bu da mesajın kendisini gereksiz kılar. –

+0

Fikir için teşekkür ederiz! Dispose() harika, ama bir şekilde onu etiket üzerinde kullanmam gerekiyor. – miri

+0

Eh, hayır, Eminim ki, Etiket'i yok etmek istemezsiniz, bu onu yok eder ve kodunuzu çökertir. Bitmap'i atın. –

İlgili konular