2012-01-05 22 views
8

मैं एक .NET Windows सेवा जो कुछ कार्रवाई करता है और रिपोर्ट तैयार करता बनाया है कारण बनता है। ये रिपोर्ट एक्सपीएस दस्तावेज हैं जिन्हें मैं एक निश्चित निर्देशिका में सहेजता हूं।एक एक्सपीएस फाइल करने के लिए एक FixedDocument सहेजा जा रहा है स्मृति रिसाव

डब्ल्यूपीएफ से परिचित होने के नाते, जिस तरह से मैंने रिपोर्ट बनाने के लिए चुना है, System.Windows.Documents.FixedDocument को तत्काल करने के लिए FixedPage ऑब्जेक्ट्स को त्वरित रूप से जोड़ना है।

मेरे समस्या यह है कि सेवा स्मृति के उपयोग के रूप में यह चलाता है समय के साथ और ऊपर और ऊपर जाता है।

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

मैंने पाया कि सेवा इन FixedDocument रिपोर्ट तैयार करता है, और उन्हें एक्सपीएस फ़ाइलें, FixedDocument वस्तुओं (Dispatcher, FixedPage, UIElementCollection, Visual, आदि) स्मृति में रह रहे हैं के साथ जुड़े सभी विभिन्न UI तत्व के रूप में सहेज लेती है।

ऐसा प्रतीत नहीं होता है जब मैं अपने डब्ल्यूपीएफ ऐप्स में एक ही काम करता हूं, और इसलिए मेरा झुकाव यह है कि डब्ल्यूपीएफ यूआई डिस्पैचर मॉडल के साथ इसका उपयोग कुछ WPF ऐप के बाहर किया जा रहा है।

मैं अपने FixedDocument वस्तुओं जब उन्हें एक सेवा इस तरह (या सामान्य रूप में एक WPF अनुप्रयोग के बाहर) में उपयोग करते हुए "निपटाने" कर सकते हैं?

======== संपादित =========

ठीक है, मैं पाया है कि मेरी स्मृति रिसाव विशेष रूप से बनाने/एक FixedDocument को आबाद करने के साथ क्या करना नहीं है। अगर मैं ऐसा करता हूं, लेकिन वास्तव में इसे एक्सपीएस के रूप में डिस्क पर सहेजता नहीं है, तो स्मृति रिसाव नहीं होता है। इसलिए, मेरी समस्या को एक्सपीएस फ़ाइल के रूप में सहेजने के साथ करना होगा।

यहाँ मेरी कोड है:

var paginator = myFixedDocument.DocumentPaginator; 
var xpsDocument = new XpsDocument(filePath, FileAccess.Write); 
var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);       
documentWriter.Write(paginator); 
xpsDocument.Close(); 

मैं क्या कोशिश की है:

  • मैनुअल कचरा संग्रहण
  • के रूप में इस सवाल का जवाब में सुझाव यह paginator हो रही (पहले कॉलिंग myFixedDocument के प्रत्येक पृष्ठ पर UpdateLayout() नीचे) - मैं भी myFixedDocumentWrite() यानी paginator नहीं
  • में सीधे गुजर की कोशिश की है 0
  • अपने स्वयं के सूत्र में कोड की उन पंक्तियों लाना और मैन्युअल रूप से नीचे बंद प्रेषक

फिर भी प्रयास विफल।

========== कारगर युक्तियाँ ==========

http://msdn.microsoft.com/en-us/library/system.appdomain.aspx पर सामान्य विधि उदाहरण में दिखाया गया का उपयोग कर अपने AppDomain में उपरोक्त कोड को अलग करके, मेमोरी रिसाव अब मेरी सेवा को प्रभावित नहीं करता है (मैं कहता हूं "अब प्रभावित नहीं होता है" क्योंकि यह अभी भी होता है, लेकिन जब ऐपडोमेन अनलोड हो जाता है, तो सभी लीक किए गए संसाधन इसके साथ अनलोड किए जाते हैं)।

मैं अभी भी एक वास्तविक समाधान को देखने के लिए उत्सुक हो जाएगा।

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

===== ===== समाधान ==========

अंतिम समाधान के लिए नीचे मेरा उत्तर देखें।

+0

जांच लगभग सटीक नकल: कि करने के लिए http://stackoverflow.com/questions/5883779/how-to-dispose-a-fixeddocument – Nat

+0

अपुष्ट जवाब प्रश्न जीसी कचरा संग्रह को मजबूर करना है। जबकि मुझे यह एक स्वीकार्य समाधान नहीं लगता है, मैंने वैसे भी कोशिश की और यह मेरे लिए काम नहीं किया। फिर भी धन्यवाद। – Ross

उत्तर

15

मैं अंत में एक जवाब, जो दो भागों है पाया से बचने के लिए .UpdateLayout() में कम से कम एक बार कॉल करनी होगी लग रहा है।

सबसे पहले,/डिस्क और समापन के लिए अपने एक्सपीएस दस्तावेज़ को सहेजने XpsDocument निपटाने के बाद, मैं निम्न कोड पंक्ति चलाएँ:

Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.SystemIdle, new DispatcherOperationCallback(delegate { return null; }), null); 

यह सब Dispatcher स्मृति में चारों ओर फांसी वस्तुओं से छुटकारा मिलता है।

उपर्युक्त स्मृति समस्याओं में से अधिकांश को देखते हुए, मैंने देखा कि अभी भी अन्य UI ऑब्जेक्ट्स के साथ फिक्स्ड पेज ऑब्जेक्ट्स मेमोरी में हैं। मैन्युअल रूप से मेरी FixedDcoument बाहर समाशोधन उनमें से छुटकारा पाने के लिए लगता है:

foreach (var fixedPage in FixedDocument.Pages.Select(pageContent => pageContent.Child)) { 
    fixedPage.Children.Clear(); 
} 
+0

इसके लिए एक गुच्छा धन्यवाद, महान सामान! –

+1

धन्यवाद आदमी, मैं " ऐपडोमेन "मार्ग, लेकिन यह अच्छी तरह से काम करता प्रतीत होता है! मैंने यह भी सत्यापित किया कि यह वास्तव में माइक्रोसॉफ्ट का मुद्दा है जहां फिक्स्ड डॉक्यूमेंट स्थिर संपत्ति" सेरिअलीज़ेबल ऑब्जेक्ट कॉन्टेक्स्ट "से जुड़ा हुआ है और इसे कभी भी रिलीज़ नहीं किया गया है। इस तरह की स्मृति रिसाव बताती है। –

+0

thnaks आदमी, जीवन रक्षा समाधान;) – Miran

0

this से, ऐसा लगता है जैसे आप स्मृति रिसाव

+0

उस प्रश्न को एक्सपीएस दस्तावेज़ खोलने के साथ करना है, स्मृति में फिक्स्ड डॉक्यूमेंट ऑब्जेक्ट्स नहीं बना रहा है। भले ही, मैंने UpdateLayout() के कॉल के संबंध में उल्लेख किए गए विभिन्न समाधानों की कोशिश की, और हां, मेरे लिए कोई भी काम नहीं करता :-( – Ross

+0

क्या आप उस कोड का हिस्सा पोस्ट कर सकते हैं जहां यह समस्या उत्पन्न करता है। मैं यह कहने में सहायता कर सकता हूं कि यह कहां से आता है। – Nat

+0

मैंने थोड़ा सा जानकारी और कुछ नमूना कोड के साथ अपना जवाब संपादित किया - अगर आपको लगता है कि आपको एक समाधान दिखाई दे रहा है जो बहुत ही अच्छा होगा। – Ross