2012-06-19 61 views
15

में टाइमर का उपयोग कैसे करें I टाइमर बनाने के लिए system.Timers.Timer का उपयोग कर रहा हूं।टाइमर में सी #

public System.Timers.Timer timer = new System.Timers.Timer(200); 
private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.Enabled = true; 
    timer.Elapsed += new System.Timers.ElapsedEventHandler(send); 
    timer.AutoReset = true; 
} 

public void send(object source, System.Timers.ElapsedEventArgs e) 
{ 
    this.rtbMsg.AppendText("psyche-->" + receiver + ": hello\n"); 
} 

भेजने समारोह में रिसीवर एक पैरामीटर है कि मैं जब समारोह प्रयोग किया जाता है निर्धारित करने की आवश्यकता है, लेकिन जब मैं भेजने समारोह में एक पैरामीटर जोड़ सकते हैं, जैसे:

public void send(object source, System.Timers.ElapsedEventArgs e,string receiver) 

तो यह एक त्रुटि फेंकता है। एमएसडीएन की जांच करने के बाद, यह कहा गया कि ElapsedEventArgs केवल इन फ़ंक्शंस के लिए उपलब्ध है जो डेटा नहीं बनाएंगे।

मैं कैसे इस समस्या को हल कर सकते हैं? मेरा प्रोग्राम विंडोज़ नहीं है। फर्म, इसलिए मैं System.Windows.Forms.Timer का उपयोग नहीं कर सकता।

+0

ठीक है, आप 'System.Windows.Forms.Timer' उपयोग करें यदि आप पुस्तकालय के लिए एक संदर्भ जोड़ सकते हैं। – annonymously

+0

संबंधित [system.timers.timer पर प्रेषक पैरामीटर को कैसे पास करें] (http://stackoverflow.com/questions/6368399/how-to-pass-the-the-sender-parameter-to-the- सिस्टम -टिमर्स-टाइमर) – Damith

+0

आपको किसी भी यूआई घटकों के साथ System.Windows.Timer का उपयोग नहीं करना चाहिए (उदाहरण के लिए rtbMsg.AppendText संभवतः कुछ प्रकार के विंडोज नियंत्रण तक पहुंच सकता है), System.Timer.Elapsed को गैर UI थ्रेड पर कॉल किया जाता है और इसका कारण बनता है ज्यादातर मामलों में एक अपवाद। यदि आप WinForms नहीं हैं और WPF हैं, तो आप एक डिस्पैच टाइमर का उपयोग करना चाहेंगे। यदि आप स्पष्ट कर सकते हैं कि आपको कौन सी त्रुटि मिल रही है, तो कोई अधिक सटीक सलाह प्रदान करने में सक्षम हो सकता है। –

उत्तर

19

आप ईवेंट हैंडलर कॉलबैक में अतिरिक्त पैरामीटर पास नहीं कर सकते हैं, क्योंकि आप इसे कॉल करने वाले नहीं हैं - टाइमर है; कि पूरे मुद्दे ;-)

है लेकिन, आप आसानी से एक बंद के साथ एक ही प्रभाव को पूरा कर सकते हैं:

private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.Elapsed += (timerSender, timerEvent) => send(timerSender, timerEvent, receiver); 
    timer.AutoReset = true; 
    timer.Enabled = true; 
} 

public void send(object source, System.Timers.ElapsedEventArgs e, string receiver) 
{ 
    this.rtbMsg.AppendText("psyche-->" + receiver + ": hello\n"); 
} 

अब बीत चुके हैंडलर (timerSender, timerEvent) => लैम्ब्डा कार्रवाई है, जो receiver से अधिक चर बंद कर देता है और कहता है send जब भी लैम्ब्डा ट्रिगर होता है तो अतिरिक्त पैरामीटर के साथ मैन्युअल रूप से।

अपने विशेष मामले में आपको प्रेषक या तर्क की आवश्यकता नहीं है, इसलिए उन्हें अग्रेषित करने की कोई आवश्यकता नहीं है। कोड बन जाता है:

private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.Elapsed += (s_, e_) => OnTimerElapsed(receiver); 
    timer.AutoReset = true; 
    timer.Enabled = true; 
} 

private void OnTimerElapsed(string receiver) 
{ 
    this.rtbMsg.AppendText("psyche-->" + receiver + ": hello\n"); 
} 

यदि आप इन सब के ऊपर के बारे में सोच रहे हैं, तो यह बहुत कम है। लैम्ब्डास सिर्फ सिंटैक्टिक चीनी हैं और दृश्यों के पीछे सादे कार्य हैं (घटना सामग्री के लिए कुछ स्वचालित प्रतिनिधि लपेटने के साथ)। क्लोजर-जेनरेटेड क्लासेस का उपयोग करके क्लोजर लागू किए जाते हैं, लेकिन जब तक आपके पास वास्तव में टन नहीं है तब तक आपको कोई कोड ब्लोट नहीं दिखाई देगा।

जैसा कि टिप्पणियों में बताया गया है, आप OnTimerElapsed कोड में यूआई तत्व तक पहुंचने लगते हैं - चूंकि आप विंडोज फॉर्म टाइमर का उपयोग नहीं कर रहे हैं, इसलिए एक अच्छा मौका है कि आप इसे करने के बाद अपवाद प्राप्त करेंगे यह कोड उस घटना को चलाएगा जब टाइमर घटना को सक्रिय करता है, और विंडोज में यूआई नियंत्रण को केवल तक बनाए गए थ्रेड से एक्सेस किया जाना चाहिए।

आप कर सकते थे गंदगी के आसपास this.Invoke साथ इसे मैन्युअल रूप से ठीक करने के लिए, लेकिन यह टाइमर मार्शल SynchronizingObject property के माध्यम से आप के लिए सही धागा करने के लिए घटना के लिए आसान है:

private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.SynchronizingObject = this; // Assumes `this` implements ISynchronizeInvoke 
    timer.Elapsed += (s_, e_) => OnTimerElapsed(receiver); 
    timer.AutoReset = true; 
    timer.Enabled = true; 
} 

अंत में, एक और से प्रेरित टिप्पणी, यहां एक और तरीका है कि आप बंद करने के संदर्भ को संग्रहीत कर सकते हैं ताकि आप बाद में घटना से सदस्यता समाप्त कर सकें:

private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.SynchronizingObject = this; // Assumes `this` implements ISynchronizeInvoke 
    ElapsedEventHandler onElapsed; 
    onElapsed = (s_, e_) => { 
     timer.Elapsed -= onElapsed; // Clean up after firing 
     OnTimerElapsed(receiver); 
    }; 
    timer.Elapsed += onElapsed; 
    timer.AutoReset = true; 
    timer.Enabled = true; 
} 
+0

ऑटोरेसेट सेट करने से पहले टाइमर क्यों शुरू करें और वापस कॉल करें? timer.Enabled = सत्य आप आखिरी चीज होना चाहिए – nbrooks

+0

@nbrooks: अच्छा बिंदु, मैं बस ओपी के कोड की प्रतिलिपि बना रहा था। मैं इसे संपादित करूंगा कि – Cameron

+0

@nbrooks टाइमर के समान है। स्टार्ट()? – Damith

3

आप नहीं कर सकते इस तरह के एक ईवेंट हैंडलर को अतिरिक्त पैरामीटर पास करें।

ऑब्जेक्ट लेवल वैरिएबल में अपना मान स्टोर करें ताकि इसे ईवेंट हैंडलर में एक्सेस किया जा सके।

private string receiver; 

public System.Timers.Timer timer = new System.Timers.Timer(200); 
private void btnAutoSend_Click(object sender, EventArgs e) 
{ 
    timer.Enabled = true; 
    receiver = 'your val'; 
    timer.Elapsed += new System.Timers.ElapsedEventHandler(send); 
    timer.AutoReset = true; 
} 

public void send(object source, System.Timers.ElapsedEventArgs e) 
{ 
    this.rtbMsg.AppendText("psyche-->" + receiver + ": hello\n"); 
} 
2
public partial class Form2 : Form 
{ 
    Timer timer = new Timer(); 
    public Form2() 
    { 
     InitializeComponent(); 
     timer.Tick += new EventHandler(timer_Tick); // Every time timer ticks, timer_Tick will be called 
     timer.Interval = (10) * (1000);    // Timer will tick every 10 seconds 
     timer.Start();        // Start the timer 
    } 
    void timer_Tick(object sender, EventArgs e) 
    { 
     //MessageBox.Show("Tick");     // Alert the user 
     var time = DateTime.Now; 
     label1.Text = $"{time.Hour} : {time.Minute} : {time.Seconds} : {time.Milliseconds}"; 
    } 
    private void Form2_Load(object sender, EventArgs e) 
    { 

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