2010-03-29 13 views
5

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

मेरी धागा में, के बाद एक्स सेकंड (एक TTimer का प्रयोग करके) बीत चुके हैं, मैं फोन:

procedure TPollingThread.OnTimer(Sender: TObject); 
var 
SystemProbeValues : TCWProbeValues; 
begin 
SystemProbeValues := Remote.Run.GetSystemProbeValues; 
PostMessage(ParentHandle, WM_APIEVENT ,Integer(apiMultiCellStatus), Integer(SystemProbeValues)); 
end; 

समारोह Remote.Run.GetSystemProbeValues ​​निम्नलिखित प्रोटोटाइप है:

function GetSystemProbeValues : TCWProbeValues; stdcall; 

और TCWProbeValues टीसीडब्लूप्रोब वैल्यू ऑब्जेक्ट्स की गतिशील सरणी है (जो सभी ट्रायमटेबल से निकलती हैं)।

मेरी मुख्य रूप में, मैं ठीक संदेश प्राप्त होता है और lParam वापस TCWProbeValues ​​लिए डाली:

procedure TFrmCWMain.OnAPIEvent(var msg: TMessage); 
begin 
ProbeValues := TCWProbeValues(msg.LParam); 
end; 

मेरा प्रश्न, दिया जाता है कि गतिशील सरणी और अपनी वस्तुओं डेल्फी HTTORIO प्रणाली द्वारा बनाया गया था, उन्हें मुक्त करने के लिए कौन जिम्मेदार है? क्या डेल्फी इस बात पर विचार करता है कि मेरे ऑनटीमर फ़ंक्शन के बाद मेमोरी फिर से प्रयोग योग्य हो गई? (और इस मामले में, मेरी शुद्ध शुभकामनाएं कि मेरा मुख्य रूप संदेश हैंडलर वास्तव में संदेश के एलपीराम द्वारा संदर्भित स्मृति को पढ़ सकता है?) या फिर, क्या यह मेरी ज़िम्मेदारी है कि ऑब्जेक्ट को HTTPRIO अनुरोध द्वारा ऑटो-इंस्टीट्यूट किया गया हो?

बहुत धन्यवाद, अगर उपरोक्त को अधिक विस्तार/कोड की आवश्यकता है तो कृपया चिल्लाओ और मैं इसमें जोड़ दूंगा!

चीयर्स, डंकन

उत्तर

4

TRemotable अपने DataContext संपत्ति के माध्यम से जीवन भर के प्रबंधन प्रदान करता है, तो साबुन क्रम वस्तु ही खाली हो जाएगा। जब तक डेटा-संदर्भ ऑब्जेक्ट मौजूद है, तब तक आवंटित सब कुछ भी मौजूद होगा। यदि आप किसी ऑब्जेक्ट के स्वामित्व और ज़िम्मेदारी का दावा करना चाहते हैं, तो बस इसकी DataContext संपत्ति साफ़ करें। (यह शायद इसलिए है क्योंकि अपने एपीआई घटना संदेश के बाद साबुन घटना समाप्त कर दिया है संभाला जा सकता है तो आप इस मामले में क्या करना चाहते हैं क्या है।)


अपने कोड में एक समस्या यह है कि आप एक गतिशील गुजर रहे हैं एक पोस्ट संदेश के माध्यम से सरणी। जब आपकी OnTimer प्रक्रिया अपने कॉलर पर वापस आती है, तो SystemProbeValues द्वारा संदर्भित गतिशील सरणी में इसकी संदर्भ गणना कम हो जाएगी। यदि अन्य थ्रेड ने अभी तक संदेश को संसाधित नहीं किया है (और शायद यह नहीं है), तो उस संदेश को संसाधित करने के लिए उस समय तक गतिशील सरणी नष्ट हो सकती है।

इसके आसपास का आसान तरीका टाइमर के ईवेंट हैंडलर में संदर्भ गणना को कम किए बिना संदर्भ को साफ़ करना है, और उसके बाद संदेश हैंडलर में विपरीत करें। ,

LParam(SystemProbeValues) := 0; 

अपने संदेश हैंडलर में वैश्विक ProbeValues चर के पुराने मूल्य स्पष्ट और इस तरह नई मूल्य निर्दिष्ट: आप संदेश पोस्ट करने के बाद, चर स्पष्ट

ProbeValues := nil; 
LParam(ProbeValues) := Msg.LParam; 

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

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