सी # में टाइमर से सटीक टिक प्राप्त करना

मैं एक पुराना मेट्रोनोम एप्लिकेशन पुनर्निर्माण करने की कोशिश कर रहा हूं जिसे मूल रूप से सी ++ में एमएफसी का उपयोग करके लिखा गया था जिसे सी # का उपयोग करके .NET में लिखा जाना है। जिन मुद्दों में मैं दौड़ रहा हूं उनमें से एक टाइमर को सटीक रूप से "टिक" करने के लिए प्राप्त कर रहा है।

उदाहरण के लिए, 120 का एक आसान बीपीएम (बीट्स प्रति मिनट) मानते हुए, टाइमर को हर 5 सेकंड (या 500 मिलीसेकंड) पर टिकटें चाहिए। हालांकि, टिकों के आधार के रूप में इसका उपयोग करना पूरी तरह से सटीक नहीं है क्योंकि .NET केवल गारंटी देता है कि आपका टाइमर बीत चुके समय से पहले टिक नहीं टिकेगा।

वर्तमान में, ऊपर इस्तेमाल किए गए उसी 120 बीपीएम उदाहरण के लिए इसे पाने के लिए, मैं 100 मिलीसेकंड की तरह टिकों को स्थापित कर रहा हूं और केवल 5 वें टाइमर टिक पर क्लिक ध्वनि चला रहा हूं। इससे सटीकता में काफी सुधार होता है, लेकिन अगर एक हैक की तरह लगता है।

तो, सटीक टिक प्राप्त करने का सबसे अच्छा तरीका क्या है? मुझे पता है कि विंडोज़ टाइमर टाइमर की तुलना में अधिक टाइमर उपलब्ध हैं जो विजुअल स्टूडियो में आसानी से उपलब्ध हैं, लेकिन मैं वास्तव में उनसे परिचित नहीं हूं।

0
ro fr bn

6 उत्तर

सी ++ एप्लिकेशन का उपयोग कर क्या है? आप हमेशा एक ही चीज़ का उपयोग कर सकते हैं या सी ++ से सी ++/सीएलआई कक्षा में टाइमर कोड लपेट सकते हैं।

0
जोड़ा

.NET में 'टाइमर' नामक तीन टाइमर कक्षाएं हैं। ऐसा लगता है कि आप विंडोज फॉर्म का उपयोग कर रहे हैं, लेकिन वास्तव में आपको सिस्टम मिल सकता है। थ्रेडिंग। टिमर क्लास अधिक उपयोगी है - लेकिन सावधान रहें क्योंकि यह पूल थ्रेड पर वापस कॉल करता है, इसलिए आप सीधे अपने फॉर्म से बातचीत नहीं कर सकते कॉलबैक

Win32 मल्टीमीडिया टाइमर - टाइम गेटटाइम, टाइमसेट पीरियड इत्यादि के लिए एक अन्य दृष्टिकोण पी/आह्वान करना हो सकता है।

A quick Google found this, which might be useful http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

इस संदर्भ में खोजने के लिए 'मल्टीमीडिया' (टाइमर) buzz-word है।

0
जोड़ा

टाइमर कक्षाएं अजीब तरीके से व्यवहार करना शुरू कर सकती हैं जब टाइमर 'टिक' ईवेंट कोड निष्पादित नहीं होता है जब तक कि अगला 'टिक' होता है। इसका मुकाबला करने का एक तरीका टिक घटना की शुरुआत में टाइमर को अक्षम करना है, फिर अंत में इसे पुनः सक्षम करें।

हालांकि, यह दृष्टिकोण उन मामलों में उपयुक्त नहीं है जहां टिक के समय में 'टिक' कोड का निष्पादन समय स्वीकार्य त्रुटि नहीं है, क्योंकि उस समय टाइमर अक्षम हो जाएगा (गिनती नहीं)।

यदि टाइमर को अक्षम करना एक विकल्प है, तो आप निष्पादित एक अलग थ्रेड बनाकर एक ही प्रभाव प्राप्त कर सकते हैं, एक्स मिलीसेकंड, निष्पादन, नींद आदि के लिए सोता है ...

0
जोड़ा
सही। मैं अगले टिक के समय को इंगित करने में सक्षम नहीं होने के बारे में आपने जो कहा उससे सहमत हूं। मैं जो कह रहा हूं उसका मुद्दा यह है कि आप पिछली टिक से टिक इवेंट कोड निष्पादित नहीं करना चाहते हैं जब आपका अगला टिक होता है।
जोड़ा लेखक Brad Barker, स्रोत
लेकिन फिर आप केवल यह सुनिश्चित कर सकते हैं कि थ्रेड कम से कम x मिलीओसेकंड सोता है; थ्रेड शेड्यूलर प्रमाणित नहीं करता है कि थ्रेड सटीक मिलसॉन्ड गिनती पर चलाएगा
जोड़ा लेखक Wilhelm, स्रोत

System.Windows.Forms.Timer is limited to an accuracy of 55 milliseconds...

0
जोड़ा
@MajesticRa: msdn.microsoft.com/en-us/लाइब्रेरी/& hellip; पीले रंग के बॉक्स में पाठ देखें
जोड़ा लेखक Anthony Sottile, स्रोत
क्या इसमें कुछ आधिकारिक दस्तावेज है?
जोड़ा लेखक MajesticRa, स्रोत
धन्यवाद! जब मैंने इसे लिखा तो मुझे इस बिंदु से चूक गया कि याज़ानप्रू का मतलब बिल्कुल फॉर्म टाइमर है। और सोचा कि वह आम तौर पर टाइमर के बारे में बात कर रहा है। लेकिन आपकी प्रतिक्रिया के लिए बहुत बहुत धन्यवाद!
जोड़ा लेखक MajesticRa, स्रोत

I have had this problem when developing a recent data-logging project. The problem with the .NET timers ( windows.forms, system.threading, and system.timer ) is that they are only accurate down to around 10 milli seconds which is due to the event scheduling built into .NET I believe. ( I am talking about .NET 2 here ). This wasn't acceptable for me and so I had to use the multimedia timer ( you need to import the dll ). I also wrote a wrapper class for all the timers and so you can switch between them if necessary using minimal code changes. Check out my blog post here: http://www.indigo79.net/archives/27

0
जोड़ा

एक और संभावना यह है कि DispatcherTimer के wpf कार्यान्वयन में एक बग है (मिलीसेकंड और टिक्स के बीच एक विसंगति है जो सटीक प्रक्रिया निष्पादन समय के आधार पर संभावित गलतता उत्पन्न करती है), जैसा कि नीचे प्रमाणित है:

http://referencesource.microsoft.com/#WindowsBase /Base/System/Windows/Threading/DispatcherTimer.cs,143

class DispatcherTimer
{
    public TimeSpan Interval
    {
        set
        {
            ...
            _interval = value;
           //Notice below bug: ticks1 + milliseconds [Bug1]
            _dueTimeInTicks = Environment.TickCount + (int)_interval.TotalMilliseconds;
        }
    }
}

http://referencesource.microsoft.com/#WindowsBase/Base /System/Windows/Threading/Dispatcher.cs

class Dispatcher
{
    private object UpdateWin32TimerFromDispatcherThread(object unused)
    {
        ...
        _dueTimeInTicks = timer._dueTimeInTicks;
        SetWin32Timer(_dueTimeInTicks);
    }

    private void SetWin32Timer(int dueTimeInTicks)
    {
        ...
       //Notice below bug: (ticks1 + milliseconds) - ticks2  [Bug2 - almost cancels Bug1, delta is mostly milliseconds not ticks]
        int delta = dueTimeInTicks - Environment.TickCount; 
        SafeNativeMethods.SetTimer( 
            new HandleRef(this, _window.Value.Handle),
            TIMERID_TIMERS,
            delta);//<-- [Bug3 - if delta is ticks, it should be divided by TimeSpan.TicksPerMillisecond = 10000]
    }
}

http://referencesource.microsoft.com/#WindowsBase/Shared /MS/Win32/SafeNativeMethodsCLR.cs,505

class SafeNativeMethodsPrivate
{
    ...
    [DllImport(ExternDll.User32, SetLastError = true, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
    public static extern IntPtr SetTimer(HandleRef hWnd, int nIDEvent, int uElapse, NativeMethods.TimerProc lpTimerFunc);
}

http://msdn.microsoft .com/en-us/पुस्तकालय/विंडोज़/डेस्कटॉप/ms644906% 28v = vs.85% 29.aspx

uElapse [in]
Type: UINT
The time-out value, in milliseconds.//<-- milliseconds were needed eventually
0
जोड़ा