2008-09-25 21 views
12

Bunu yapan bir ASP.Net uygulamada bazı C# kodu var:GDI + System.Drawing.Bitmap hata Parametre geçerli değil verir aralıklı

Bitmap bmp = new Bitmap (1184, 1900);

Ve bazen "Parametre geçerli değil" bir istisna atar. Şimdi etrafta dolaşıyordum ve görünüşe göre GDI + rastgele istisnalar atmaktan gurur duyuyor ve pek çok insan bu sorunu yaşıyordu, ama hiç kimsenin bir çözümü yok! Sistemi kontrol ettim ve hem RAM hem de takas alanı bol. Şimdi geçmişte 'iisreset' yaparsam sorun gider, ama birkaç gün içinde geri dönüyor. Ama ben bir bellek sızıntısı neden olduğuna ikna değilim, çünkü yukarıda belirtildiği gibi ram + takas ücretsiz bol.

Herhangi bir çözümü olan var mı?

cevap

1

Sadece yeterli belleğe gereksiniminiz yok, bitişik olması gerekiyor. Zaman içinde bellek parçalanır ve büyük blokları bulmak zorlaşır. Daha küçük bitmap'lerden görüntüler oluşturmanın yanı sıra, bunun için pek çok iyi çözüm yoktur.

yeni Bitmap (x, y) hemen hemen belleği ayırmaya ihtiyaç duyuyor - programınızın bir şekilde bozuk olmadığını varsayarak (yığının bozulmasına neden olabilecek herhangi bir güvenli kod var mı), o zaman bununla başlayacağım tahsis başarısız. Bitişik bir bloğa ihtiyaç duyulması, görünüşte küçük bir tahsisin nasıl başarısız olabileceğidir. Yığının parçalanması, genellikle özel bir ayırıcıyla çözülen bir şeydir - bunun, IIS'de (veya mümkün) iyi bir fikir olduğunu sanmıyorum.

Bellekte ne tür bir hata olduğunu görmek için, yalnızca bir test olarak devasa bir Bitmap ayırmayı deneyin - hangi hatayı atar bakın. Gördüğüm bir strateji, bazı büyük bellek bloklarını önceden ayırmak (sizin durumunuzda Bitmap'ler) ve bunları bir havuz olarak ele almak (almak ve havuza geri döndürmek). Sadece kısa bir süreliğine bunlara ihtiyacınız varsa, sadece bir kaç hafızayı tutarak ve paylaşarak uzaklaşabilirsiniz.

+0

1184x1900x32bit'lik bir bit eşlem ~ 9 megavattır. Bu, bitişik bir bloğu güvenilir bir şekilde istemek için gerçekten çok mu fazla? –

0

Sadece microsoft desteğinden bir yanıt aldım. Burada bakmak Anlaşılan eğer:

http://msdn.microsoft.com/en-us/library/system.drawing.aspx

Bunu birinin içinde bu sınıfları kullanmaya çalışmak System.Drawing ad içinde Sınıflar Windows veya ASP.NET hizmeti içinde kullanılmak için desteklenmez" diyor görebilirsiniz. Bu uygulama türleri arasında, hizmet performansı ve çalışma zamanı istisnaları gibi beklenmedik sorunlar oluşabilir. " Yani temelde onların ellerini yıkıyorlar. .Net çerçevesinin bu bölümünün güvenilmez olduğunu kabul ettikleri anlaşılıyor. Biraz hayal kırıklığına uğradım.

Sıradaki - Gif dosyası açmak, bazı metinleri yerleştirmek ve tekrar kaydetmek için benzer bir kitaplık önerebilir misiniz?

3

Bağlamda bugüne kadar gördüğüm her şey, bellek sızıntıları/sap kaçaklarıyla ilgilidir. Kodunuzu incelemek için yeni bir göz çifti almanızı öneririm.

Gerçekte olan şey, önceki kod satırında oluşturmuş olsanız bile, görüntünün gelecekte rastgele bir noktaya yerleştirilmiş olmasıdır. Bunun nedeni bir bellek/tanıtıcı sızıntısı olabilir (kodumdan bazılarının temizlenmesine rağmen bu sorunu düzeltir gibi görünüyor).

Bu hata, uygulama bir süredir kullanımdan sonra gerçekleşebileceğinden, bazen çok fazla bellek kullanıldığında, bazen, çöp toplayıcısının, hizmetlerle ilgili bazı özel ayarlamalar nedeniyle kurallara uymadığını hissediyorum; Microsoft neden bu problemi kendi elleriyle yıkıyor.

http://blog.lavablast.com/post/2007/11/The-Mysterious-Parameter-Is-Not-Valid-Exception.aspx

+0

Bunun böyle olabileceğini düşündüm, bu yüzden System.bitmap nesnesindeki Dispose işlevini çağırdım, sorunu çözmemiş miydim? –

10

Dur kullanarak GDI + ve WPF Görüntüleme sınıfları (.NET 3.0) kullanmaya başlayın. Bunlar GDI + sınıflarının büyük bir temizleme ve performans için ayarlanmış. Ek olarak, bitmap üzerinde birden çok eylemi verimli bir şekilde kolayca gerçekleştirmenizi sağlayan bir "bitmap zinciri" oluşturur. ilgilenen herkes için

using System.Windows.Media.Imaging; 
class Program { 
    public static void Main(string[] args) { 
     var bmp = new WriteableBitmap(1184, 1900, 96.0, 96.0, PixelFormat.Bgr32, null); 
    } 
} 
+2

Bu iyi bir cevap. Ne yazık ki sınırlı değilim. Net 2. –

+1

Asp.net içinde işleme hakkında ne? System.Windows yok ... – nerijus

6

, çözüm i kullanmak için gidiyorum:

yaklaşık BitmapSource

İşte sadece bazı pikselleri almayı bekleyen boş bir bitmap ile başlayan bir örnek okuyarak daha fazla bul system.drawing yerine mono C# dağıtımından Mono.Cairo kitaplıklarıdır. Eğer mono.cairo.dll, libcairo-2.dll, libpng13.dll ve zlib1.dll dosyalarını mono sürümünün Windows sürümlerinden benim yürütülebilir dosyam ile aynı klasöre sürüklüyorsam, o zaman Visual Studio 2005 kullanarak pencerelerde gelişebilir ve Her şey güzel çalışıyor.

Güncelleme - Yukarıdakileri yaptım ve uygulamam stresi test ettim ve şimdi her şey sorunsuz çalışıyor gibi görünüyor ve önyükleme için 200 m'ye kadar daha az ram kullanıyor. Çok mutlu. System.Drawing ad içinde

0

Sınıflar desteklenen bir alternatif için Windows veya ASP.NET hizmeti

içinde kullanılmak için desteklenmez, bkz Windows Imaging Components (msdn), ironik System.Drawing dayanan bir yerli kütüphane .