2012-02-02 13 views
9

मुझे पता है कि सी # और विंडोज फॉर्म में Thread.Sleep और System.Windows.Forms.Timer और Monitor.Wait है। मैं बस एक्स सेकेंड के लिए इंतजार कैसे कर सकता हूं और फिर कुछ और कर सकता हूं - धागे को लॉक किए बिना।अतुल्यकालिक रूप से x सेकंड के लिए प्रतीक्षा करें और फिर कुछ निष्पादित करें?

मेरे पास एक बटन है। बटन पर एक टाइमर शुरू होगा और 5 सेकंड के लिए प्रतीक्षा करें। इन 5 सेकंड के बाद फॉर्म पर कुछ अन्य नियंत्रण रंगीन हरा है। Thread.Sleep का उपयोग करते समय, पूरा एप्लिकेशन 5 सेकंड के लिए उत्तरदायी नहीं होगा - तो मैं बस "5 सेकंड के बाद कुछ कैसे करूं"?

+3

बस System.Windows.Forms.Timer' का उपयोग '। टाइमर को 5 सेकंड के लिए सेट करें, और 'टिक' ईवेंट को संभालें। जब घटना आग लगती है, तो बात करें। – Ben

+2

हम सी # 5 में एक नई सुविधा जोड़ रहे हैं जो इस प्रकार के एसिंक्रोनस ऑपरेशन को बहुत आसान बनाता है; यदि आप एक चुपके चोटी पाने में रुचि रखते हैं, तो इस ब्लॉग पोस्ट से शुरू करें: http://blogs.msdn.com/b/csharpfaq/archive/2011/04/13/async-ctp-sp1-refresh.aspx –

+0

वे माइक्रोसॉफ्ट जाने के लिए! –

उत्तर

23

(टिप्पणी के रूप में बेन से लिखित)

सिर्फ System.Windows.Forms.Timer का उपयोग करें। टाइमर को 5 सेकंड के लिए सेट करें, और टिक ईवेंट को संभालें। जब घटना आग लगती है, तो बात करें।

...और दूसरी बार दबाने के लिए अपने काम करने से पहले टाइमर (IsEnabled = false) को अक्षम करें।

टिक घटना एक और धागा कि आपका GUI संशोधित नहीं कर सकते पर क्रियान्वित किया जा सकता है, तो आप इस पकड़ कर सकते हैं:

private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 

    private void StartAsyncTimedWork() 
    { 
     myTimer.Interval = 5000; 
     myTimer.Tick += new EventHandler(myTimer_Tick); 
     myTimer.Start(); 
    } 

    private void myTimer_Tick(object sender, EventArgs e) 
    { 
     if (this.InvokeRequired) 
     { 
      /* Not on UI thread, reenter there... */ 
      this.BeginInvoke(new EventHandler(myTimer_Tick), sender, e); 
     } 
     else 
     { 
      lock (myTimer) 
      { 
       /* only work when this is no reentry while we are already working */ 
       if (this.myTimer.Enabled) 
       { 
        this.myTimer.Stop(); 
        this.doMyDelayedWork(); 
        this.myTimer.Start(); /* optionally restart for periodic work */ 
       } 
      } 
     } 
    } 

बस संपूर्णता के लिए: async/का इंतजार है, एक कुछ पर अमल में देरी कर सकते के साथ बहुत आसान (एक शॉट, मंगलाचरण दोहराने कभी नहीं):

private async Task delayedWork() 
{ 
    await Task.Delay(5000); 
    this.doMyDelayedWork(); 
} 

//This could be a button click event handler or the like */ 
private void StartAsyncTimedWork() 
{ 
    Task ignoredAwaitableResult = this.delayedWork(); 
} 

अधिक के लिए, देखें "async और इंतजार" MSDN में। पोस्ट जवाब के रूप में चिह्नित में

+0

उपरोक्त, अच्छी पूर्ण व्याख्या। – Ben

+1

'.BeginInvoke (myTimer_Tick, प्रेषक, ई)' काम नहीं करता है क्योंकि "तर्क प्रकार विधि समूह सिस्टम के लिए असाइन करने योग्य नहीं है। –

+1

पीएस: यदि अंतराल 5 सेकेंड तक नहीं था तो आपको कुछ लॉकिंग की आवश्यकता होगी पहले टाइमर को अक्षम करने का मौका मिलने से पहले एक दूसरे टिक को निष्पादित करने से रोकें। – mtijn

2

आपका एप्लिकेशन लटकता है क्योंकि आप मुख्य यूआई थ्रेड पर 5 सेकंड नींद/प्रतीक्षा का आह्वान कर रहे हैं। नींद/प्रतीक्षा करें/जो भी एक अलग थ्रेड में कार्रवाई करें (वास्तव में System.Windows.Forms.Timer आपके लिए यह करना चाहिए) और जब यह पूरा हो जाता है तो उस क्रिया को आह्वान करता है जो कुछ नियंत्रण हरे रंग को बदल देता है। InvokeRequired जांचना याद रखें। यहाँ एक छोटा नमूना (setText, एक और धागे से कहा जा सकता है अगर यह कॉल के बजाय मुख्य यूआई धागे पर लागू हो जाएगा जहां पाठ बॉक्स पर है):

private void SetText(string text) 
{ 
// InvokeRequired required compares the thread ID of the 
// calling thread to the thread ID of the creating thread. 
// If these threads are different, it returns true. 
if (this.textBox1.InvokeRequired) 
{  
    SetTextCallback d = new SetTextCallback(SetText); 
    this.Invoke(d, new object[] { text }); 
} 
else 
{ 
    this.textBox1.Text = text; 
} 
} 

मैं here से (अच्छी तरह से लायक नमूना ले लिया एक पढ़ा!)।

+0

मैं "क्रॉस-थ्रेड ऑपरेशन मान्य नहीं है: नियंत्रण 'बटन' को थ्रेड के अलावा किसी थ्रेड से एक्सेस किया गया है, जिस पर बनाया गया था।" तब अपवाद? –

+1

नियंत्रण देखें। इन्वोक – Onkelborg

+1

आग्रह जादू है। महान! –

0

मुझे लगता है कि आप क्या देख रहे हैं System.Timers है ... मुझे नहीं लगता कि आपको ऐसा करने के लिए एक सीडब्ल्यूएनडी टाइमर सेट करने की आवश्यकता है: उदाहरण के लिए http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx पर एक नज़र डालें। यह चाल करना चाहिए।

+0

System.Windows.Forms.Timer, यह थ्रेड का उपयोग नहीं कर रहा है। –

8

आप एक अतुल्यकालिक कार्य है कि आपके कार्रवाई करता है शुरू कर सकते हैं:

Task.Factory.StartNew(()=> 
{ 
    Thread.Sleep(5000); 
    form.Invoke(new Action(()=>DoSomething())); 
}); 

[संपादित करें] आप बस एक चर में संग्रहीत करने के लिए है में

अंतराल पास करने के लिए:

int interval = 5000; 
Task.Factory.StartNew(()=> 
{ 
    Thread.Sleep(interval); 
    form.Invoke(new Action(()=>DoSomething())); 
}); 

[/ EDIT]

+0

यह काम करेगा। हालांकि मुझे लगता है कि मैं अंतराल को पास करना चाहता हूं। –

+1

कोई अच्छा विचार नहीं है। आप यहाँ 5 सेकंड के लिए पूल थ्रेड का अपहरण करते हैं। और फिर आप थ्रेड को बंद करने के लिए केवल Invoke() का उपयोग करें। –

+0

@ टोनी होपकिन्सन मैंने अंतराल को पारित करने के लिए उदाहरण बढ़ाया। – PVitt

1

आप इसे गलत देख रहे हैं। बटन पर क्लिक करें, यह x सेकंड के अंतराल के साथ टाइमर बंद करता है। जब वे ऊपर होते हैं तो यह घटनाक्रम कार्य को निष्पादित करता है।

तो आप क्या नहीं करना चाहते हैं।

जबकि एक्स सेकंड समाप्त हो रहे हैं।

जबकि कार्य निष्पादित हो रहा है?

उदाहरण के लिए यदि आप देरी और कार्य पूरा होने तक बटन को क्लिक नहीं करना चाहते हैं। बटन में इसे अक्षम करें हैंडलर पर क्लिक करें, और इसे कार्य पूर्ण करने पर सक्षम करें।

यदि आप चाहते हैं कि कार्य से पहले पांच सेकंड की देरी हो, तो आपको कार्य में देरी शुरू होनी चाहिए और इसे ख्याल रखना चाहिए।

0

@eFloh ने कहा:

टिक घटना एक और धागा कि अपने जीयूआई संशोधित नहीं कर सकते पर निष्पादित किया जा सकता, तो आप इस पकड़ कर सकते हैं ...

दस्तावेज़ों का कहना नहीं है।
आप अपने उदाहरण कोड में System.Windows.Forms.Timer का उपयोग कर रहे हैं।
यह फॉर्म है। टिमर
सी # दस्तावेज़ों के अनुसार टाइमर घटनाओं को यूआई थ्रेड पर उठाया जाता है।

यह विंडोज टाइमर एक एकल पिरोया वातावरण जहां यूआई धागे प्रसंस्करण प्रदर्शन करने के लिए उपयोग किया जाता है के लिए बनाया गया है। यह जरूरी है कि उपयोगकर्ता कोड एक यूआई संदेश पंप उपलब्ध है और हमेशा एक ही धागे से संचालित ...

भी देखें stackoverflow post here

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

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