2012-04-02 24 views
20

ठीक है तो मैं System.Timers.Timer का उपयोग कर रहा हूं .Net 4 के साथ सी #।मैं ऑब्जेक्ट को टाइमर ईवेंट में कैसे पास करूं?

var timer = new Timer {Interval = 123}; 

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

timer.Elapsed += MyElapsedMethod; 

और मेरे विधि इस प्रकार है:

मैं इतनी तरह मेरे टाइमर वस्तु है

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine("Foo Bar"); 
} 

मैं इस विधि में एक स्ट्रिंग पास करना चाहता हूं, मैं यह कैसे कर सकता हूं?

धन्यवाद

उत्तर

48

यह करने के लिए सबसे आसान तरीका है एक गुमनाम समारोह में ईवेंट हैंडलर को बदलने के लिए है। यह आपको घोषणा के बिंदु पर स्ट्रिंग को पारित करने की अनुमति देता है।

string theString = ...; 
timer.Elapsed += (sender, e) => MyElapsedMethod(sender, e, theString); 

static void MyElapsedMethod(object sender, ElapsedEventArgs e, string theString) { 
    ... 
} 
+2

वास्तव में आप अभी भी कुछ वैश्विक चर पढ़ रहे हैं (हाँ, यह स्थानीय हो सकता है, लेकिन इसका कोई मतलब नहीं है)। इवेंट हैंडलर को अज्ञात फ़ंक्शन के साथ बदल दिया गया है। यह 'टाइमर। हटाया गया + = (एस, ई) => कंसोल। राइटलाइन (द स्ट्रिंग); 'यहां तक ​​कि छोटा, लेकिन वही विचार। –

+0

मैंने सोचा कि इवेंटहाउंडर्स इनलाइन असाइन करना निराश है क्योंकि उन्हें बाद में रिलीज़ नहीं किया जा सकता है? –

2

आप किसी वस्तु में स्ट्रिंग बचाने के लिए और ईवेंट हैंडलर में यह पढ़ सकते हैं: timer.Elapsed += (s,e) => Console.WriteLine(_value);

अद्यतन: भी प्रणाली के उपयोग पर विचार अलग वाक्य रचना के माध्यम से एक ही कोड:

static string _value; 

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine(_value); 
} 

अद्यतन । थ्रेडिंग। इसके बजाय

State state = new State(); 
Timer timer = new Timer(OnTimer, state, 0, 123); 
state.Value = "FooBar"; // change state object 

आप टाइमर कॉलबैक में स्थिति पुन: प्राप्त कर सकते हैं:

static void OnTimer(object obj) 
{ 
    State state = obj as State; 
    if (state == null) 
     return;   

    Console.WriteLine(state.Value); 
} 
+0

हम्म मैं यही कर रहा था, मैं एक और सीधा मार्ग ढूंढ रहा था! – JMK

0

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

12

यदि आप फिर से अपने "विलुप्त" ईवेंट हैंडलर को अनधिकृत करने में सक्षम होना चाहते हैं, तो आपको किसी वैरिएबल में इसे याद किए बिना प्रतिनिधि का उपयोग नहीं करना चाहिए।

तो टाइमर पर आधारित कस्टम क्लास बनाने का एक और समाधान हो सकता है। बस जो कुछ भी आप की तरह सदस्यों और वापस "बीता" ईवेंट हैंडलर के "प्रेषक" तर्क से अपने कस्टम टाइमर वस्तु मिल जोड़ें:

class CustomTimer : System.Timers.Timer 
{ 
    public string Data; 
} 

private void StartTimer() 
{ 
    var timer = new CustomTimer 
    { 
     Interval = 3000, 
     Data = "Foo Bar" 
    }; 

    timer.Elapsed += timer_Elapsed; 
    timer.Start(); 
} 

void timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    string data = ((CustomTimer)sender).Data; 
} 

निश्चित रूप से यह रणनीति अन्य घटनाओं और कक्षाओं के लिए काम करता है भी, के रूप में रूप में लंबे समय बेस क्लास सील नहीं है।

0
Timer aTimer = new Timer(300); 
       aTimer.Elapsed += delegate { PublishGPSData(channel, locationViewModel); }; 
       // Hook up the Elapsed event for the timer. 
       aTimer.AutoReset = true; 
       aTimer.Enabled = true; 
private void PublishGPSData(IModel channel, LocationViewModel locationViewModel) 
{ 
}; 
संबंधित मुद्दे