2016-07-21 8 views
5

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

  1. जब उपयोगकर्ता क्लिक पर क्लिक करता है तो थ्रेड को समाप्त और मुक्त करें और प्रारंभ होने पर एक नया बनाएं।
  2. थ्रेड में देरी करने के लिए नींद का उपयोग करें (मैं यह नहीं करना चाहता)
  3. एक ऐसी संपत्ति है जो यह निर्धारित करने के लिए एक बूलियन है कि धागा रुक गया है या नहीं। निष्पादन में कोड केवल तभी होगा जब यह बूलियन झूठा हो।

मैं # 3 की ओर झुका रहा हूं। मुख्य रूप से TThread ऑब्जेक्ट पर एक बूलियन प्रॉपर्टी सेट करना थ्रेडसेफ होना चाहिए?

इनमें से कौन सा विकल्प, या कोई बेहतर विकल्प, क्या मुझे जाना चाहिए? यह पहली बार धागे का उपयोग कर रहा है ताकि किसी भी मदद की सराहना की जा सके।

+2

डेल्फी के हाल के संस्करण थ्रेड को रोकने/फिर से शुरू करने की अनुमति नहीं देते हैं, क्योंकि संपूर्ण डिज़ाइन (और अवधारणा) त्रुटिपूर्ण था। आपको ऐसा करने का प्रयास करने से बचने चाहिए और इसके बजाय सिग्नल किए गए ईवेंट (उदा।, टीवेन्ट) का उपयोग करने के लिए स्विच करना चाहिए। SyncObjs में विभिन्न ईवेंट प्रकार देखें। –

+1

यह भी देखें http://stackoverflow.com/questions/4401171/self-suspending-a-thread-in-delphi-when-its-not-needed-and-safely-resuming – kludg

उत्तर

9

1. उपयोगकर्ता क्लिक बंद होने पर थ्रेड को मुक्त और मुक्त करें जब वे प्रारंभ क्लिक करते हैं तो एक नया बनाएं।

यह निश्चित रूप से एक विकल्प है, अगर ओवरहेड न्यूनतम है।

3. एक संपत्ति है जो यह निर्धारित करने के लिए एक बूलियन है कि धागा रुक गया है या नहीं। निष्पादन में कोड केवल तभी होगा जब यह बूलियन झूठा हो।

आप ऐसा कर सकते हैं, लेकिन आपको नियमित रूप से उस बूलियन की जांच करनी होगी और यदि सेट हो तो प्रतीक्षा प्रतीक्षा लूप दर्ज करें जब तक कि इसे साफ़ नहीं किया जाता है या धागा को समाप्त करने के लिए संकेत दिया जाता है।

मुख्य रूप से टीटीएचड ऑब्जेक्ट पर बूलियन प्रॉपर्टी सेट करना थ्रेडसेफ होना चाहिए?

यह धागा सुरक्षित TThread.Terminate() बुला, जो केवल बूलियन TThread.Terminated संपत्ति सेट के रूप में के रूप में है।

इनमें से कौन सा विकल्प, या कोई बेहतर विकल्प, क्या मुझे जाना चाहिए?

मैं विकल्प # 4 का उपयोग करता हूं - बूलियन के बजाय संकेतित घटनाओं का उपयोग करके। उदाहरण के लिए:

type 
    TMyThread = class(TThread) 
    private 
    FRunEvent, FTermEvent: TEvent; 
    FWaitEvents: THandleObjectArray; 
    procedure CheckPause; 
    protected 
    procedure Execute; override; 
    procedure TerminatedSet; override; 
    public 
    constructor Create; reintroduce; 
    destructor Destroy; override; 
    procedure Pause; 
    procedure Unpause; 
    end; 

constructor TMyThread.Create; 
begin 
    inherited Create(False); 

    FRunEvent := TEvent.Create(nil, True, True, ''); 
    FTermEvent := TEvent.Create(nil, True, False, ''); 

    SetLength(FWaitEvents, 2); 
    FWaitEvents[0] := FRunEvent; 
    FWaitEvents[1] := FTermEvent; 
end; 

destructor TMyThread.Destroy; 
begin 
    FRunEvent.Free; 
    FTermEvent.Free; 
    inherited; 
end; 

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    begin 
    // do some work... 
    CheckPause; 
    // do some more work... 
    CheckPause; 
    // do some more work... 
    CheckPause; 
    //... 
    end; 
end; 

procedure TMyThread.TerminatedSet; 
begin 
    FTermEvent.SetEvent; 
end; 

procedure TMyThread.CheckPause; 
var 
    SignaledEvent: THandleObject; 
begin 
    while not Terminated do 
    begin 
    case TEvent.WaitForMultiple(FWaitEvents, INFINITE, False, SignaledEvent) of 
     wrSignaled: begin 
     if SignaledEvent = FRunEvent then Exit; 
     Break; 
     end; 
     wrIOCompletion: begin 
     // retry 
     end; 
     wrError: begin 
     RaiseLastOSError; 
    end; 
    end; 
    SysUtils.Abort; 
end; 

procedure TMyThread.Pause; 
begin 
    FRunEvent.ResetEvent; 
end; 

procedure TMyThread.Unpause; 
begin 
    FRunEvent.SetEvent; 
end; 
+0

रेमी, 'SysUtils.Abort;' के लिए उपयोग की गई 'चेकपॉज़' विधि में क्या है। –

+0

यह थ्रेड को तुरंत समाप्त करने के लिए 'ईएबॉर्ट' अपवाद उठाता है (क्योंकि 'निष्पादन() 'इसे पकड़ नहीं लेता है) अगली बार' टर्मिनेशन() 'को कॉलिनेशन()' के नाम से बुलाया जाता है। –

-1

चेक बाहर शुरू करने और यहां धागे को रोकने पर डेल्फी के लिए विकी: http://docwiki.embarcadero.com/RADStudio/Berlin/en/Starting_and_Stopping_Threads

यह यह आगे वापस लागू हो सकता है, लेकिन मैं पहले के संस्करणों पुष्टि नहीं कर सकते रूप में वापस दूर डेल्फी 7. के रूप में लागू है।

+2

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

+2

स्टैक ओवरफ़्लो में आपका स्वागत है। आपने सवाल का जवाब नहीं दिया है। प्रश्न एक सिफारिश का अनुरोध करता है, लेकिन आपने एक प्रदान करने के लिए उपेक्षित किया है। कृपया अपना उत्तर संपादित करें ताकि यह पता चल सके कि प्रश्न क्या पूछता है। –

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