2009-11-05 10 views
12

सिस्टम: विंडोज एक्सपी एसपी 3, .NET 3.5, 4 जीबी रैम, डुअल 1.6 जीएचजेआप कैसे सुनिश्चित करते हैं कि डब्ल्यूपीएफ मेमोरी से बड़े बिटमैप स्रोत जारी करता है?

मेरे पास एक WPF एप्लिकेशन है जो लोड और संक्रमण (स्टोरीबोर्ड एनिमेशन का उपयोग करके) बहुत बड़े पीएनजी है। संकल्प में ये पीएनजी 8190x1080 हैं। जैसे ही एप्लिकेशन चलता है, यह छवियों को कैश करने के लिए प्रतीत होता है और सिस्टम मेमोरी धीरे-धीरे बढ़ जाती है। आखिरकार यह सिस्टम को चकित करता है और आउटऑफमेमरी अपवाद फेंकता है।

1) मैं एप्लिकेशन

2) मैं कोई नहीं करने के लिए BitmapSource BitmapCacheOption की स्थापना कर रहा हूँ जब मैं लोड से BitmapSource तत्वों को हटा कर रहा हूँ:

ये कदम उठाएँ मैं वर्तमान में हल करने के लिए इस प्रयास करने के लिए ले रहा हूँ कर रहे हैं BitmapSource

3) मैं BitmapSource बर्फ़ीली रहा एक बार यह भरा हुआ है।

4) मैं छवि स्रोत के साथ ही स्रोत से ही कोई भी संदर्भ का उपयोग करता है के सभी संदर्भ को हटाने कर रहा हूँ।

5) ऊपर दिए गए चरणों के बाद मैन्युअल रूप से जीसी.कोलेक्ट() को कॉल करना पूरा हो गया है।

क्यों WPF इन छवियों के लिए स्मृति और एक संभव समाधान पर व्यतीत कर रहा है सुनिश्चित करने के लिए है कि उन्हें लोड करने के लिए इस्तेमाल किया स्मृति ठीक से वसूल किया जाता है यह पता लगाने की उम्मीद है।

उत्तर

21

आपने निश्चित रूप से इस पर बहुत सारे काम किए हैं। मुझे लगता है कि मुख्य समस्या यह है कि बिटमैप कैशऑप्शन। कोई अंतर्निहित बिटमैप डिकोडर को कैश होने से नहीं रोकता है।

एक GC.Collect(),) फिर से कर 300 विभिन्न Uris से 300 छोटे छवियों को लोड, और GC.Collect (बुला के रूप में इस तरह के करने के लिए कई मुश्किल समाधान कर रहे हैं, लेकिन सरल एक सीधा है:

एक उरी से लोड करने के बजाय, बस एक स्ट्रीम का निर्माण और यह BitmapFrame के निर्माता को पारित:

var source = new BitmapImage(); 
using(Stream stream = ...) 
{ 
    source.BeginInit(); 
    source.StreamSource = stream; 
    source.CacheOption = BitmapCacheOption.OnLoad; // not a mistake - see below 
    source.EndInit(); 
} 

कारण यह काम करना चाहिए एक धारा से है कि लोड हो रहा है पूरी तरह से कैश अक्षम करता है। न केवल शीर्ष-स्तरीय स्रोत कैश नहीं किया गया है, बल्कि आंतरिक डिकोडरों में से कोई भी कैश नहीं किया जाता है।

क्यों BitmapCacheOption.OnLoad? यह counterintuitive लगता है, लेकिन इस झंडे के दो प्रभाव हैं: कैशिंग सक्षम होने पर यह कैशिंग सक्षम बनाता है, और यह एंडइनिट() पर लोड होने का कारण बनता है। हमारे मामले में कैशिंग असंभव है, इसलिए यह सब लोड को तुरंत होने का कारण बनता है।

जाहिर है आप इस कोड, तो आप इसे ऊपर ले जा सकते हैं अपने यूआई धागा बंद चलाने BitmapSource फ्रीज करना चाहते हैं।

तुम भी आश्चर्य हो सकता है कारण है कि मैं BitmapCreateOptions.IgnoreImageCache उपयोग नहीं किया। इस तथ्य के अलावा कि किसी भी यूआरआई के साथ कैशिंग असंभव है, IgnoreImageCache छवि कैश को पूरी तरह से अनदेखा नहीं करता है: यह केवल पढ़ने के लिए इसे अनदेखा करता है। तो अगर IgnoreImageCache सेट किया गया है, तो लोड की गई छवि अभी भी कैश में डाली गई है। अंतर यह है कि कैश में मौजूदा छवि को नजरअंदाज कर दिया जाता है।

+0

बिटमैप स्रोत स्रोत = नया बिटमैप स्रोत() संकलित नहीं होगा और मुझे यकीन नहीं है कि क्यों। इस त्रुटि को फेंकता है: त्रुटि अमूर्त वर्ग या इंटरफ़ेस 'System.Windows.Media.Imaging.BitmapSource' – discorax

+0

Ahh..it संकलित नहीं करता है जब मैं बिटमैप स्रोत के बजाय बिटमैप छवि का उपयोग करता हूं। अब, इससे समस्याएं कैसे पैदा होंगी? :) – discorax

+0

यह दृष्टिकोण अब तक आशाजनक प्रतीत होता है। मैं परीक्षण जारी रखूंगा। – discorax

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

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