2008-09-25 9 views
12

मैं एक ASP.Net अनुप्रयोग है कि यह करता है में कुछ सी # कोड है:GDI + System.Drawing.Bitmap त्रुटि पैरामीटर मान्य नहीं है देता है रुक-रुक कर

बिटमैप bmp = नए बिटमैप (1184, 1900);

और कभी-कभी यह एक अपवाद फेंकता है "पैरामीटर मान्य नहीं है"। अब मैं चारों ओर घूम रहा हूं और स्पष्ट रूप से जीडीआई + यादृच्छिक अपवाद फेंकने के लिए कुख्यात है, और बहुत से लोगों को यह समस्या है, लेकिन किसी के पास इसका कोई समाधान नहीं है! मैंने सिस्टम की जांच की है और इसमें रैम और स्वैप स्पेस दोनों हैं। अतीत में अगर मैं 'iisreset' करता हूं तो समस्या दूर हो जाती है, लेकिन यह कुछ दिनों में वापस आती है। लेकिन मुझे विश्वास नहीं है कि मैंने मेमोरी लीक का कारण बना दिया है, क्योंकि जैसा कि मैंने ऊपर कहा है वहां बहुत सारे रैम + स्वैप मुक्त हैं।

किसी के पास कोई समाधान है?

उत्तर

1

आपको केवल पर्याप्त स्मृति की आवश्यकता नहीं है, इसे संगत होने की आवश्यकता है। समय के साथ स्मृति खंडित हो जाती है और बड़े ब्लॉक खोजने में मुश्किल हो जाती है। छोटे बिटमैप्स से छवियों को बनाने के अलावा, इसके लिए बहुत अच्छे समाधान नहीं हैं।

नया बिटमैप (एक्स, वाई) बहुत मेमोरी को आवंटित करने की आवश्यकता है - यह मानते हुए कि आपका प्रोग्राम किसी भी तरह से दूषित नहीं है (क्या कोई असुरक्षित कोड है जो ढेर को दूषित कर सकता है), तो मैं इसके साथ शुरू करूंगा आवंटन विफल रहा है। एक संगत ब्लॉक की आवश्यकता यह है कि एक छोटा सा आवंटन कैसे विफल हो सकता है। ढेर का टुकड़ा ऐसा कुछ है जो आमतौर पर एक कस्टम आवंटक के साथ हल किया जाता है - मुझे नहीं लगता कि यह आईआईएस (या संभव) में एक अच्छा विचार है।

यह देखने के लिए कि आप स्मृति से क्या त्रुटि प्राप्त करते हैं, केवल एक परीक्षण के रूप में एक विशाल बिटमैप आवंटित करने का प्रयास करें - देखें कि यह किस त्रुटि में फेंकता है।

एक रणनीति जो मैंने देखी है वह स्मृति के कुछ बड़े ब्लॉक (आपके मामले बिटमैप्स में) आवंटित करना है और उन्हें पूल के रूप में व्यवहार करना (उन्हें पूल में ले जाना और वापस करना)। यदि आपको केवल थोड़े समय के लिए उनकी आवश्यकता है, तो आप कुछ को स्मृति में रखने और उन्हें साझा करने से दूर हो सकते हैं।

+0

1184x1900x32bits का बिटमैप ~ 9 मेग्स होगा। क्या वास्तव में एक संगत ब्लॉक के लिए वास्तव में बहुत कुछ पूछना है? –

0

मुझे अभी माइक्रोसॉफ्ट समर्थन से एक जवाब मिला है। आप यहाँ देखने के लिए जाहिरा तौर पर करता है, तो:

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

आप देख सकते हैं यह कहते हैं, "System.Drawing नाम स्थान के अंदर वर्ग एक विंडोज़ या ASP.NET सेवा के भीतर उपयोग के लिए समर्थित नहीं हैं किसी एक से इन कक्षाओं में उपयोग करने के लिए प्रयास कर रहा है। इन अनुप्रयोग प्रकारों में अप्रत्याशित समस्याएं उत्पन्न हो सकती हैं, जैसे कम सेवा प्रदर्शन और रन-टाइम अपवाद। " तो वे मूल रूप से इस मुद्दे के अपने हाथ धो रहे हैं। ऐसा प्रतीत होता है कि वे स्वीकार कर रहे हैं कि नेट फ्रेमवर्क का यह अनुभाग अविश्वसनीय है। मैं थोड़ा निराश हूँ।

अगला - क्या कोई भी एक gif फ़ाइल खोलने के लिए एक समान लाइब्रेरी की सिफारिश कर सकता है, कुछ पाठ को अतिरंजित कर सकता है, और इसे फिर से सहेज सकता है?

3

मेरे संदर्भ में जो कुछ भी मैंने देखा है, वह स्मृति लीक/हैंडल लीक से संबंधित है। मैं आपको अपने कोड की जांच करने के लिए आंखों की एक नई जोड़ी प्राप्त करने की सलाह देता हूं।

वास्तव में क्या होता है यह है कि छवि भविष्य में एक यादृच्छिक बिंदु पर निपटाई गई है, भले ही आपने इसे कोड की पिछली पंक्ति पर बनाया हो। यह स्मृति/हैंडल रिसाव के कारण हो सकता है (मेरे कोड में से कुछ को साफ करने के लिए प्रतीत होता है लेकिन इस समस्या को पूरी तरह से हल नहीं करता है)।

चूंकि यह त्रुटि थोड़ी देर के लिए उपयोग में आने के बाद होती है, कभी-कभी बहुत सारी मेमोरी का उपयोग करते हुए, कभी-कभी मुझे लगता है कि कचरा कलेक्टर नियमों से संबंधित कुछ विशेष बदलावों के कारण नियमों का पालन नहीं करता है और यह है माइक्रोसॉफ्ट इस समस्या के अपने हाथ क्यों धोता है।

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

+0

मैंने सोचा कि ऐसा हो सकता है, इसलिए मैंने सुनिश्चित किया कि मैं system.bitmap ऑब्जेक्ट पर डिस्पोजेक्ट फ़ंक्शन को कॉल करता हूं, क्या इससे समस्या हल नहीं होती? –

10

GDI का उपयोग कर बंद करो + और WPF इमेजिंग वर्गों (.NET 3.0) का उपयोग शुरू करते हैं। ये जीडीआई + कक्षाओं का एक प्रमुख सफाई है और प्रदर्शन के लिए ट्यून किए गए हैं। इसके अतिरिक्त, यह एक "बिटमैप श्रृंखला" सेट करता है जो आपको बिटमैप पर एक कुशल तरीके से आसानी से कई क्रियाएं करने की अनुमति देता है।

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

यह एक अच्छा जवाब है। दुर्भाग्य से मैं .NET 2. –

+1

तक सीमित हूं asp.net में प्रतिपादन के बारे में क्या? कोई सिस्टम नहीं। वहाँ बताता है ... – nerijus

6

जो कोई रुचि है, तो समाधान मैं का उपयोग करने के लिए जा रहा हूँ:

के बारे में BitmapSource

यहाँ एक खाली बिटमैप के साथ शुरू बस कुछ पिक्सल प्राप्त करने के लिए इंतजार कर रहे, इसका एक उदाहरण पढ़कर अधिक जानकारी प्राप्त करें System.drawing का उपयोग करने के बजाय मोनो सी # वितरण से मोनो कैरो पुस्तकालय है। यदि मैं मोनो के विंडोज संस्करण से mono.cairo.dll, libcairo-2.dll, libpng13.dll और zlib1.dll फ़ाइलों को अपने निष्पादन योग्य के समान फ़ोल्डर में खींचता हूं, तो मैं दृश्य स्टूडियो 2005 का उपयोग कर विंडोज़ में विकसित कर सकता हूं और यह सब अच्छी तरह से काम करता है।

अपडेट - मैंने उपरोक्त किया है, और तनाव ने एप्लिकेशन का परीक्षण किया है और यह सब आसानी से चल रहा है, और बूट करने के लिए 200 एमबी कम रैम का उपयोग करता है। बहुत खुश। System.Drawing नाम स्थान के अंदर

0

कक्षा एक Windows या ASP.NET सेवा

के भीतर उपयोग के एक समर्थित विकल्प के लिए के लिए समर्थित नहीं हैं, को देखने के Windows Imaging Components (msdn), एक देशी पुस्तकालय जो विडंबना यह है कि System.Drawing पर आधारित है ।

संबंधित मुद्दे