2014-09-04 4 views
5

के बराबर सी # भाषा मैं एक आरएफ रीडर डिवाइस के साथ काम कर रहा हूं जिसमें सी # एपीआई है। इसकी एपीआई पर आधारित, आपको कार्ड को पढ़ने/बैज करने के लिए मैन्युअल रूप से अपने पढ़ने के फ़ंक्शन को आवेक करना होगा।सी # भाषा अनुसूचितExecutorService

तो मेरा कामकाज टाइमर का उपयोग प्रत्येक 'एन' सेकंड पढ़ने के लिए करना है।

मेरी समस्या यह है कि टाइमर लगातार निष्पादन कर रहा है, भले ही Thread.sleep() को इसके क्रिया के अंदर बुलाया गया हो।

Timer timer = new Timer(TimerCallback, null, 500, 1000); // From main() method 

// The action that Timer executes 
private void TimerCallback(Object o) 
{ 
    scan(); // Action for reading/badging card 
    scand.WaitOne(); // AutoResetEvent(true) 
    GC.Collect(); // Force garbage collection 
} 

थ्रेड.sleep() स्कैन() के अंदर आक्रमण।

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

मुझे उम्मीद है कि इस कारण से मुझे एक कामकाज है जितनी जल्दी हो सके मुझे इसकी आवश्यकता है।

धन्यवाद!

+0

आप टास्क वर्ग पर एक नजर है किया ? http://stackoverflow.com/questions/13211334/how-do-i-wait-until-task-is-finished-in-c – fuchs777

+0

जब मैं खोज रहा हूं तो मैंने कार्य वर्ग देखा लेकिन कोड @ एर्नो डी वीरड को हल किया गया मेरी समस्या। लेकिन वैसे भी धन्यवाद। –

उत्तर

2

कॉलबैक में टाइमर को फिर से शुरू करके सबसे विश्वसनीय तरीका मुझे मिल सकता था। सक्रिय होने पर कॉलबैक बाधित नहीं होता है।

Timer timer = new Timer(TimerCallback, null, 500, 0); 

private void TimerCallback(Object o) 
{ 
    scan(); 
    scand.WaitOne(); 
    timer.Change(500, 0); 
} 

timer.Change टाइमर को फिर से शेड्यूल करता है।

नोट: मैंने टाइमर स्टार्टअप में पुनरावृत्ति को हटा दिया।

बीटीडब्ल्यू: मैंने GC.Collect() हटा दिया क्योंकि मैं ज्यादातर मामलों में खराब अभ्यास और बेकार मानता हूं।

इसके अतिरिक्त आप विधि की शुरुआत (प्रयोग Stopwatch) में समय मिल सकता है और आवश्यक समय डेल्टा गणना timer.Change को पास करने की:

Timer timer = new Timer(TimerCallback, null, 500, 0); 
Stopwatch stopwatch = Stopwatch.StartNew(); 

private void TimerCallback(Object o) 
{ 
    var entered = stopwatch.ElapsedMilliseconds; 
    scan(); 
    scand.WaitOne(); 
    var duration = stopwatch.ElapsedMilliseconds - entered; 
    var delay = Math.Max(0, 500 - duration); 
    timer.Change(delay, 0); 
} 

इस तरह कॉलबैक 500 के बाद सक्रिय किया जाएगा एमएस कम से कम स्कैन कार्यों को निष्पादित करने के लिए लिया गया। इस तरह से स्थापित करें और आप स्कैन से नींद को हटा सकते हैं।

आपके कोड में डबल कॉलबैक का कारण शायद यह है कि टाइमर दूसरे थ्रेड पर कॉलबैक निष्पादित करता है जब पहला थ्रेड अभी भी कॉलबैक निष्पादित कर रहा है।

एक और समाधान टाइमर का उपयोग नहीं करना हो सकता है। बस पाश और एक समय अवधि की गणना करने के लिए एक स्टॉपवॉच का उपयोग नींद के लिए:

private void Scan() 
{ 
    while(scanning) 
    { 
     var entered = stopwatch.ElapsedMilliseconds; 
     scan(); 
     scand.WaitOne(); 
     var duration = stopwatch.ElapsedMilliseconds - entered; 
     var delay = Math.Max(0, 500 - duration); 
     Thread.Sleep(delay); 
    } 
} 

सुनिश्चित करें कि आप एक अलग थ्रेड पर इस विधि को कॉल करते हैं (यदि आप एक टास्क इस्तेमाल कर सकते हैं)

+0

आपकी संक्षिप्त प्रतिक्रिया के लिए धन्यवाद। आपका सही, मेरी समस्या यह है कि मेरा मौजूदा कोड एक अंतहीन स्थगित कॉलबैक के परिणामस्वरूप है। आपका दूसरा सचित्र कोड मैं उपयोग करता था और यह पूरी तरह से काम करता है जैसा कि मुझे चाहिए। आपकी अनुशंसित 'टाइमर। चेंज()' चाल है। धन्यवाद! –

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