2017-02-17 10 views
5

मेरे पास एक ऐसा प्रोग्राम है जो थ्रेड का उपयोग करता है जो कुछ काम करता है। धागे को प्रगति के दूसरे धागे (इस उदाहरण में मुख्य धागा) को सूचित करना चाहिए।अज्ञात प्रक्रिया में स्थानीय चर का हैंडलिंग TThread.Queue

यदि मैं सिंक्रनाइज़ करने के लिए सिंक्रनाइज़ करने के लिए() सिंक्रनाइज़ करता हूं, तो सब कुछ अपेक्षित काम करता है। अगर मैं मुख्य थ्रेड के साथ सिंक्रनाइज़ और के लिए-चर प्रकाशित करें और यह एक सूची में डाल दिया हर एक मूल्य के सही ढंग से मेरी ListBox में मुद्रित:

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Synchronize(
     procedure() 
     begin 
     FireEvent(i); 
     end); 
    end; 
end; 

आउटपुट: 1, 2, 3, 4, 5। .. 1000

अगर मैं का उपयोग कतार() तुल्यकालन आउटपुट के रूप में नहीं की उम्मीद है प्रदर्शन करने के लिए:

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Queue(
     procedure() 
     begin 
     FireEvent(i); 
     end); 
    end; 
end; 

आउटपुट: 200, 339, 562, 934, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, [...]

यहाँ क्या हो रहा है? मेरी समझ के अनुसार अनाम प्रक्रिया को परिवर्तनीय "i" पर कब्जा करना चाहिए?

+0

पीएस: मुझे पता है कि यह अक्सर यूआई को अपडेट करने के लिए ज्यादा समझ में नहीं आता है। मैं सिर्फ यह जानना चाहता हूं कि परिवर्तनीय सामग्री को पूरी तरह से बदलने के लिए क्या किया जाता है, अनामिक विधि को मूल्य को कैप्चर करना चाहिए। –

+1

आप चर को कैप्चर करते हैं। लेकिन आप "मूल्य" को पकड़ने की कोशिश कर रहे हैं। तो आपको लूप के प्रत्येक पुनरावृत्ति के लिए एक नया चर बनाने की आवश्यकता है, और इसे कैप्चर करें। इसके लिए एक नया ढेर फ्रेम की आवश्यकता होती है, और इसलिए एक फ़ंक्शन कॉल की आवश्यकता होती है। जो एलयूआरडी के जवाब में कोड की ओर जाता है। –

उत्तर

5

अज्ञात प्रक्रिया चर संदर्भ को कैप्चर करती है। इसका मतलब है कि अज्ञात प्रक्रिया चलने पर मान अनिश्चित है।

आदेश एक मूल्य पर कब्जा करने के लिए, अगर आप इस तरह एक अद्वितीय फ्रेम में लपेट करना होगा:

Type 
    TWorkerThread = class (TThread) 
    ... 
    function GetEventProc(ix : Integer): TThreadProcedure; 
    end; 

function TWorkerThread.GetEventProc(ix : Integer) : TThreadProcedure; 
// Each time this function is called, a new frame capturing ix 
// (and its current value) will be produced. 
begin 
    Result := procedure begin FireEvent(ix); end; 
end; 

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Queue(GetEventProc(i)); 
    end; 
end; 

भी देखें Anonymous methods - variable capture versus value capture

+0

यह संकलित नहीं करता है ... –

+0

'कतार (EventWithValue (i)) होना चाहिए और 'EventWithValue' को' TThreadProcedure' वापस करना चाहिए। कम से कम, मैं यही करूँगा। –

+0

प्रलेखन पढ़ें: [डेल्फी में बेनामी तरीके] (http://docwiki.embarcadero.com/RADStudio/en/Anonymous_Methods_in_Delphi), विशेष रूप से [बेनामी तरीके परिवर्तनीय बाध्यकारी] (http://docwiki.embarcadero.com/RADStudio/ एन/Anonymous_Methods_in_Delphi # Anonymous_Methods_Variable_Binding)। –

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