2012-03-02 16 views
5

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

मैं एक निम्न (छद्म) कोड और मैं चाहते हैं पता करने के लिए है

  • इसे सुरक्षित विंडोज घटना वस्तु धागे से काम कर रहा है?
  • यदि हां, तो क्या यह अवधारणा कुशल होगी?

type 
    TMyThread = class(TThread); 
    private 
    FEvent: THandle; 
    protected 
    procedure Execute; override; 
    public 
    procedure DoSomething(const AEvent: THandle); 
    end; 

procedure TMyThread.Execute; 
begin 
    // is it working with events thread safe ? 
    SetEvent(FEvent); 
    // the thread will continue, so I can't use WaitFor 
    // but it won't set this specific FEvent handle again 
    // I'm working on such kind of an action queue, so once the action with ID, 
    // here represented by the FEvent will be processed, it's removed from 
    // the action queue 
end; 

procedure TMyThread.DoSomething(const AEvent: THandle); 
begin 
    FEvent := AEvent; 
end; 

// here's roughly what I want to do 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    OnceUsedEvent: THandle; 
begin 
    // the thread is already running and it's instantiated in MyThread 
    // here I'm creating the event for the single request I need to be performed 
    // by the worker thread 
    OnceUsedEvent := CreateEvent(nil, True, False, nil); 
    try 
    // here I'm passing the event handle to the worker thread (like a kind of 
    // a request ID) 
    MyThread.DoSomething(OnceUsedEvent); 
    // and here I want to wait for 10 seconds (and also interrupt this waiting 
    // when the user closes the application if possible ?) for the thread if 
    // performs my request 
    WaitForSingleObject(OnceUsedEvent, 10000); 
    finally 
    // close the event handle 
    CloseHandle(OnceUsedEvent); 
    end; 
    // and continue with something else 
end; 

धन्यवाद!

+0

बटन ईवेंट हैंडलर में ईवेंट पर प्रतीक्षा करना मुख्य धागे को अवरुद्ध कर देगा, इसलिए यह नहीं है कि आप क्या चाहते हैं! हो सकता है कि आप इसके बजाय किसी ईवेंट का उपयोग कर सकें (जिसे थ्रेड समाप्त होने पर भी कहा जाता है) – jpfollenius

+2

वह प्रतीक्षा जो आप चाहते हैं वह करने के लिए नहीं है। इसे बाधित नहीं किया जा सकता है। और आप 10 के लिए क्यों ब्लॉक करना चाहते हैं? यह सिर्फ अजीब है। –

+0

आदर्श रूप से INFINITE; और यह कार्रवाई का नाम बदलने के लिए है। मुझे वर्चुअल ट्री व्यू नोड के संपादन मोड में प्रवेश करने की आवश्यकता है और जब तक मुझे थ्रेड से नामांकन कार्रवाई का नतीजा न हो जाए तब तक संपादक को जीवित रखें (मेरे पास एक अतिरिक्त ईवेंट हैंडलर है जहां मुझे परिणाम पारित करने की आवश्यकता है और जब मैं बाहर निकलता हूं इस घटना हैंडलर संपादक छुपा है)। –

उत्तर

4

हाँ, यह बिल्कुल ठीक है। CreateEvent से लौटाया गया हैंडल सभी थ्रेडों द्वारा स्वतंत्र रूप से उपयोग किया जा सकता है। कुछ भी इसे बहुत बेकार प्रदान करेगा क्योंकि यह इसका प्राथमिक उपयोग है :)

+1

जरूरी नहीं है। ऐसा लगता है कि एक हैंडल थ्रेड-विशिष्ट हो सकता है, या कम से कम स्वाभाविक रूप से थ्रेड-सुरक्षित नहीं हो सकता है। यदि कोई अन्य थ्रेड उसी ईवेंट तक पहुंच चाहता था, तो हो सकता है कि उसे डुप्लिकेट हैंडल को कॉल करने की आवश्यकता हो, या इसे उसी ईवेंट नाम के साथ CreateEvent को कॉल करने की आवश्यकता है। –

+0

अनुभवजन्य रूप से, हैंडल को अन्य धागे से इस्तेमाल किया जा सकता है - मैंने इस तरह से घटनाओं का उपयोग अक्सर किया है। –

+0

@RobKennedy यह वही है जो मैंने आज तक किया है जब मैंने एक उदाहरण देखा कि किसी के पास दोनों ही थ्रेड एक ही हैंडल चर का उपयोग करते हैं ... –

3

जीयूआई ईवेंट हैंडलरों में धागे की प्रतीक्षा न करें। घटनाओं, semaphores या mutexes, नींद() loops, DoEvents loops या इसके किसी भी संयोजन पर इंतजार करके ऐसा मत करो।

यदि आप थ्रेडपूल में कुछ संसाधित किए गए हैं, तो सिग्नल सिग्नल के साथ संवाद करना चाहते हैं, तो PostMessage() API देखें।

+0

मुख्य ट्रेड के साथ संवाद करते समय 'पोस्टमेसेज' का उपयोग करने के विकल्प 1) थ्रेड .Queue' जैसा कि यहां बताया गया है [सिंक्रनाइज़-एंड-क्यू-पैरा-पैरामीटर] (http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/#more-135) (यह फ़ायरमॉन्की अनुप्रयोगों के लिए उपयोगी है) या 2) 'थ्रेड सुरक्षित कतार' का उपयोग करके और टाइमर लूप के साथ मुख्य धागे से कतार को मतदान करना। –

+0

'सिंक्रनाइज़-एंड-क्यूई-इन-पैरामीटर' ओके-आईएसएच है, लेकिन यह पता लगाने के लिए कि यह कौन सा धागा चल रहा है, यह दो सिस्टम कॉल करता है :(समय-समय पर सबसे ज्यादा प्रदर्शित करने के लिए मतदान के लिए टाइमर का उपयोग करना ठीक है। कई चर के दिनांक मूल्य, लेकिन अगर कतार मतदान के लिए उपयोग किया जाता है तो बस विलंबता प्रस्तुत करता है। –

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