2010-10-28 15 views
20

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

बी मुख्य रूप से डेटा भेज रहा है और सी (सिंक्रनाइज़ेशन को कॉल करके), हमने बी के भीतर बी को समाप्त करने की कोशिश की, जबकि बी बीटरमिनेट को कॉल करके निष्पादित कर रहा है। लेकिन यह विधि काम नहीं करती है और बी अभी भी निष्पादित विधि में समाप्त होने तक काम कर रहा है।

कृपया मदद करें। पहले ही, आपका बहुत धन्यवाद।

उत्तर

41

आपको काम करने के लिए थ्रेड में टर्मिनेट की जांच करनी है। उदाहरण के लिए:

procedure TMyThread.Execute; 
begin 
    while not Terminated do begin 
    //Here you do a chunk of your work. 
    //It's important to have chunks small enough so that "while not Terminated" 
    //gets checked often enough. 
    end; 
    //Here you finalize everything before thread terminates 
end; 
इस के साथ

, आप कॉल कर सकते हैं

MyThread.Terminate; 

और यह जैसे ही यह काम का एक और हिस्सा प्रसंस्करण खत्म समाप्त होगा। इसे "सुन्दर धागा समाप्ति" कहा जाता है क्योंकि धागे को किसी भी काम को खत्म करने और समाप्ति के लिए तैयार करने का मौका दिया जाता है।

एक अन्य विधि है, जिसे 'मजबूर समाप्ति' कहा जाता है। आप कॉल कर सकते हैं:

TerminateThread(MyThread.Handle); 

जब आप ऐसा करते, विंडोज जबरदस्ती किसी भी गतिविधि सूत्र में बंद हो जाता है। इसे थ्रेड में "समाप्त" की जांच करने की आवश्यकता नहीं है, लेकिन संभावित रूप से अत्यधिक खतरनाक हो सकता है, क्योंकि आप ऑपरेशन के बीच में धागे को मार रहे हैं। आपका आवेदन उसके बाद क्रैश हो सकता है।

यही कारण है कि आप कभी भी टर्मिनेट थ्रेड का उपयोग नहीं करते हैं जब तक कि आप पूरी तरह से सुनिश्चित न हों कि आपके पास सभी संभावित परिणाम सामने आए हैं। वर्तमान में आप नहीं करते हैं, तो पहली विधि का उपयोग करें।

+1

धन्यवाद टिमो। उत्तर और उदाहरण साफ़ करें। – Dylan

+0

और खुद को धन्यवाद। एक बहुत अच्छा उदाहरण है। – Dylan

+3

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

12

टर्मिनेट एक थ्रेड को मारता नहीं है; यह उस थ्रेड को सूचित करने के लिए Terminated प्रॉपर्टी सेट करता है जिसे इसे समाप्त करने की आवश्यकता होती है। यह Terminated के लिए देखने की थ्रेड की ज़िम्मेदारी है और खुद को बंद कर दें।

3

सभी Terminate विधि यह है कि यह Terminated संपत्ति को सत्य पर सेट करता है। इसलिए आपको उस संपत्ति को मैन्युअल रूप से जांचना होगा और फिर सत्य पर सेट होने पर थ्रेड विधि से बाहर निकलना होगा।

0

यदि आप धागे को समाप्त करना चाहते हैं तो आप एक और ऐप को उछालने से बेहतर हो सकते हैं और अगर आपको लगता है कि यह असफल रहा है तो विंडोज़ आपके बाद साफ हो जाएंगी।

14

वास्तव में,

वर्तमान में सबसे मतदान इस सवाल का जवाब सही नहीं है (ताकि 34 upvoters ... के रूप में) संबंध में कैसे जबरदस्ती एक धागा को मारने के लिए।

आप TerminateThread प्रक्रिया के लिए एक पैरामीटर के रूप में नहीं उपयोग ThreadId कर ThreadId का उपयोग करने से अधिकतर "अमान्य हैंडल" त्रुटि हो सकती है या बदतर केस स्केनेरियो - एक अलग थ्रेड को मार देगा।

आप एक पैरामीटर के रूप में एक thread handle पारित करना चाहिए:

धागा के हैंडल और आईडी के बीच मतभेदों के बारे में
TerminateThread(MyThread.Handle); 

अधिक here पाया जा सकता है।

संपादित

लगता @himself मेरा उत्तर देखने के बाद अपनी गलती को सही है, तो यह अब प्रासंगिक नहीं है।

+0

@ कोबिक हां और मैंने अतीत में ऐसा किया था, लेकिन देखो कि यह समुदाय कैसे काम करता है: बहुत से लोगों ने वास्तव में यह जांच किए बिना +1 दिया कि क्या स्वयं का जवाब सही है या नहीं। – Wodzu

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