2009-12-15 18 views
5

अजीब समस्या। शायद कोई कुछ अंतर्दृष्टि दे सकता है।किसी भी तरह से दूषित जारी हैंडल?

  • परिदृश्य 1। मेरे पास स्मृति में एक TBitmap है जो जटिल पिक्सेल के रंग की गणना करने के लिए जटिल गणना के दौरान लिखा जाता है। प्रत्येक बार (आमतौर पर बिटमैप भरने वाली प्रत्येक क्षैतिज रेखा के बाद) TBitmap को एक रूप में एक छवि पर खींचा जाता है (image1.Canvas.Draw (0, 0, TBitmap)। अधिकांश समय यह ठीक काम करता है, लेकिन मैंने देखा कि यदि प्रत्येक बिटमैप लाइन के लिए कई धीमी जटिल कैल्क्स हैं (30 सेकंड से अधिक या गणना करने के लिए एक मिनट लेते हैं) तो मुख्य रूप में एक क्षणिक "झिलमिलाहट" होता है जो किसी भी तरह बिटमैप को मिटा देता है, इसलिए image.draw कॉल केवल ड्रॉ करता है नवीनतम गणना की लाइन और पहली y लाइनों बिटमैप में बाहर blanked कर रहे हैं। मैं गणना करने से पहले बिटमैप लॉक करके इस के आसपास मिला है।

  • परिदृश्य 2. यह मुख्य परेशानी। मैं एक TMemoryStream लिए लिख रहा हूँ है बिटमैप के बजाए। वही सौदा। गणना प्रत्येक पिक्सेल मान की गणना करने के लिए होती है और फिर प्रत्येक पिक्सेल मान TMemoryStream को लिखा जाता है प्रक्रिया के दौरान memstream.Write (बाइटवेल्यू, 1) के साथ। सभी गणनाओं के अंत में मैं स्ट्रीम को memstream के साथ बिटमैप में सहेजता हूं। सेवटोफाइल ('जो भी। बीएमपी') और फिर स्ट्रीम को memstream के साथ मुक्त करें। फ्री। यदि गणना त्वरित है तो धारा कोई फर्क नहीं पड़ता कि आकार क्या है (मैं 10000x10000 आयामों के साथ परीक्षण कर रहा हूं)।

मैं भी बता के रूप में मुख्य आवेदन खिड़की/रूप की तरह यह रंगा जा रहा है एक मामूली झिलमिलाहट है परिणामी फ़ाइल भ्रष्ट हो जाएगा कर सकते हैं। जब ऐसा होता है तो ऐसा लगता है जैसे बिटमैप्स और टीएममोरीस्ट्रीम के लिए हर हैंडल को मार दिया/ताज़ा किया जाता है ताकि मौजूदा डेटा दूषित हो।

कोई विचार? यह वास्तव में बेकार है। विशेष रूप से जब प्रत्येक एकल छवि को केवल यह देखने के लिए एक घंटा लग सकता है कि पृष्ठभूमि में कुछ खत्म होने पर और बिटमैप या टीएममोरीस्ट्रीम को दूषित कर दिया जाए।

क्या कोई तरीका है कि मैं एक TMmoryStream हैंडल को लॉक कर सकता हूं जैसे कि मैं बिटमैप के साथ कर सकता हूं? इससे मदद मिल सकती है। या डेल्फी को बताने के लिए कुछ घोषणा "मेरे ऑब्जेक्ट्स के साथ गड़बड़ न करें, भले ही ऐसा लगता है कि ऐप बहुत लंबा समय ले रहा है"

या क्या किसी को डेल्फी के पीछे के पीछे के कारण को पता है जो ऐसा होने का कारण बनता है।

टीएममोरीस्ट्रीम प्रक्रिया के अंदर बनाया गया है जो सभी गणनाओं को स्थानीय वस्तु है। बिटमैप मुद्दे के साथ बिटमैप प्रक्रिया के बाहर एक वैश्विक चर था और ऐसा हुआ, इसलिए मुझे नहीं लगता कि यह कारण है।

यह विंडोज 7 के तहत भी है, लेकिन मैंने Vista के तहत मूल बिटमैप समस्या देखी है।

अद्यतन 1:

क्षमा करें टिप्पणियों का उपयोग नहीं है, लेकिन वहाँ पाठ का आकार पर restirction ...

रेमी (और किसी और यह पढ़) को

जवाब में ...

है के लिए

सिंगल थ्रेडेड। गणना के त्वरित होने पर मेमोरीस्ट्रीम के लिए यह 5000x5000 रिज़ॉल्यूशन के लिए ठीक काम करता है, लेकिन यदि विफल हो तो विफल हो जाता है।

एक बुनियादी ढांचे के रूप में कोड DoCalcs अपेक्षाकृत तेजी से तो सब कुछ योजना के लिए चला जाता है, तो

SetupMemorystream; 
for y:=0 to height do 
    for x:=0 to width do 
     DoCalcs; 
     SetByteValue; 
    end; 
end; 
SaveStream; 

की तर्ज पर है। यदि यह धीमा है तो मुझे TMemoryStream भ्रष्टाचार मिलता है और परिणामस्वरूप बिटमैप स्ट्रीम को भ्रष्ट कर दिया जाता है।

यह स्मृति में टीबीआईटीएमएपी का उपयोग करने के समान था जब तक कि मुझे पता चला कि मैं बिटमैप को लॉक कर सकता हूं जो डेल्फी और/या विंडोज को "जब चाहें" को एक नए हैंडल को फिर से चालू करता है जो बिटमैप के अंदर डेटा दूषित करता है।

यह एक संयोग नहीं लगता ऐसी ही समस्या का TMemoryStream और उसके हैंडल के साथ नहीं हो रहा है की बहुत अधिक है।

अद्यतन 2:

एक और जानकारी की शायद उपयोगी बिट।

जब TMemoryStream ठीक बचाता परिणामी फ़ाइल (एक 5000x5000 बिटमैप के लिए) आकार में 75,000,054 बाइट है।

जब बचाया धारा भ्रष्ट है यह (जब संभाल दूषित है जब तक धारा सहेजा जाता है से आकार के) एक यादृच्छिक मूल्य हो रहा है। उदाहरण आकार 22 एमबी और 9 एमबी रहे हैं।

जब मैं जिसके परिणामस्वरूप फ़ाइलों को देखने के लिए एक हेक्स संपादक यह पता चलता है कि फ़ाइलों की शुरुआत हैडर मात्रा के साथ सही हैं है, लेकिन किसी भी तरह पूंछ काट समाप्त होता है।

यह बहुत विचित्र है। वैसे भी मैं निश्चित रूप से एक SaveemoFile कॉल के बाद और इसे मुक्त करने से पहले एक TMemoryStream फ्लश कर सकते हैं?

+2

क्या आपका कोड बहु-थ्रेडेड है? यदि नहीं, तो गणना की गति कोई कारण नहीं है जिन समस्याओं का आपने वर्णन किया है। आपके पास बस बग्गी कोड है जो बिटमैप/स्ट्रीम में दूषित डेटा लिख ​​रहा है। –

+0

आप हमेशा अपने प्रश्नों और उत्तरों, और आपके द्वारा पूछे गए प्रश्नों के किसी भी उत्तर पर 1 प्रतिनिधि के साथ टिप्पणी कर सकते हैं। आपको अपने प्रश्न को संपादित करने में भी सक्षम होना चाहिए। –

+0

मेमोरी स्ट्रीम केवल कक्षा में लिपटे मेमोरी का एक हिस्सा है। वीसीएल और आरटीएल किसी भी तरह से इसके साथ गड़बड़ नहीं करेंगे। तो आपकी समस्या कोड में कहीं भी होनी चाहिए। – Runner

उत्तर

0

यह सिर्फ यह सोचते हैं क्या हो रहा है द्वारा इस तरह के एक त्रुटि खोजने के लिए मुश्किल है। चूंकि ऑपरेशन इतनी लम्बाई है कि केवल दोहराना महंगा है और अगर त्रुटि मिलेगी तो प्रतीक्षा करें।

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

1

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

मुझे हाल ही में यह मिला है: यह क्यूसी 80148 में है। हालांकि इसके बारे में आप बहुत कुछ नहीं कर सकते हैं, क्योंकि विंडोज क्लोजहैंड फ़ंक्शन किसी भी त्रुटि को वापस करने की संभावना नहीं है।

1
  1. स्मृति धारा करने के लिए प्रत्येक बाइट लिखने से पहले, इतना है कि यह फिर से आकार नहीं करता स्मृति अक्सर बिट स्ट्रीम की अनुमानित आकार के लिए क्षमता की स्थापना की।हो जाएगा ताकि गति बात ऊपर

  2. मुझे लगता है कि आप पाश के लिए

चीयर्स पर ऊंचाई और चौड़ाई से 1 घटाना है

+0

+1, क्षमता बेहतर के लिए प्रदर्शन बदल जाएगी और लूपों को सबसे अधिक संभावना है y: = 0 से ऊंचाई -1 डू '। – skamradt

0

आप एक tFileStream फ्लश करने के लिए API कॉल FlushFileBuffers(filestream.Handle) उपयोग कर सकते हैं, लेकिन मेरे अनुमान है कि पहली जगह भ्रष्टाचार का कारण बनने के लिए कुछ और हो रहा है, जो आपके लूप को 1 से चौड़ाई या 0 से चौड़ाई -1 तक की तुलना में 0 से चौड़ाई तक जा सकता है ... इसका विश्लेषण किए बिना कहना मुश्किल है दिनचर्या आपकी मेमोरी स्ट्रीम को पॉप्युलेट करने के लिए कर रही हैं।

1

सभी संकेतों के लिए धन्यवाद दोस्तों। लूपों में कोड में चौड़ाई -1 के लिए सही 0 था।

समस्या चौड़ाई और ऊंचाई के चर के रूप में समस्या थी जो मुख्य रूप में आकार बदलते समय एप्लिकेशन में कहीं और बदल गए थे (वे आमतौर पर ऑनस्क्रीन प्रदर्शित छवि का ट्रैक रखते थे, लेकिन मैंने ट्रैक करने के लिए इस प्रक्रिया के अंदर एक ही चर का उपयोग किया था मेमोरीस्ट्रीम बिटमैप चौड़ाई और ऊंचाई। इसलिए जब वे लूप्स के बाहर बदल गए और उत्पादन को दूषित कर दिया। ट्रैक करने के लिए किसी समस्या का क्या एक बगजर। एक बार जब मैंने चौड़ाई और ऊंचाई चर को स्थानांतरित किया, तो सब कुछ अपेक्षित काम करता है।

I पता होना चाहिए कि यह मेरी त्रुटि थी और डेल्फी मुद्दा नहीं था।

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