Získání přesné klíšťata z časovače v jazyce C #

hlasů
14

Snažím se obnovit starou metronomu aplikaci, která byla původně napsána pomocí MFC v jazyce C ++, které mají být napsána v .NET C #. Jednou z otázek, Běžím do zmocňuje, aby časovač „tick“ dostatečně přesně.

Například za předpokladu, snadný BPM (beatů za minutu) na 120 ° C, časovač by měl zaškrtnout každých .5 sekund (nebo 500 milisekund). Použití této skutečnosti jako základ pro klíšťata, však není zcela přesné, jak NET pouze zaručuje, že vaše časovač nebude zaškrtněte předtím, než prošel uplynulý čas.

V současné době se tento postup obejít za stejné 120 BPM například použitý výše, jsem nastavení klíšťat na něco jako 100 milisekund a jen hrát cvaknutí na každém 5. časovače klíště. To však zlepšit přesnost docela dost, ale pokud se cítí jako trochu hack.

Takže, co je nejlepší způsob, jak získat přesné klíšťata? Vím, že jsou k dispozici, než je Windows Forms časovačem, který je k dispozici v Visual Studio více časovačů, ale já nejsem obeznámen s nimi.

Položena 12/08/2008 v 13:20
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
9

K dispozici jsou tři časovače třídy nazvané ‚Timer‘ v .NET. Vypadá to, že používáte Windows Forms jednu, ale ve skutečnosti byste mohli najít třída System.Threading.Timer vhodnější - ale buďte opatrní, protože zavolá zpět na niti u bazénu, takže si nemůže přímo komunikovat s formuláři ze zpětné volání.

Jiným přístupem by mohlo být p / odvolávat na multimediální časovače Win32 - timeGetTime, timeSetPeriod, atd.

Google Rychlý našel, které by mohly být užitečné http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

‚Multimedia‘ (časovač) je módní slovo hledat v této souvislosti.

Odpovězeno 12/08/2008 v 13:34
zdroj uživatelem

hlasů
1

Další možností je, že se jedná o chybu v implementaci WPF z DispatcherTimer (existuje neshoda mezi několika tisícin sekundy a klíšťata způsobují potenciální nesprávnost v závislosti na přesném čase spuštění procesu), o čemž svědčí níže:

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/library/windows/desktop/ms644906%28v=vs.85%29.aspx

uElapse [in]
Type: UINT
The time-out value, in milliseconds. // <-- milliseconds were needed eventually
Odpovězeno 18/12/2014 v 14:26
zdroj uživatelem

hlasů
1

Měl jsem tento problém při vývoji nejnovějších údajů protokolování projekt. Problém s NET časovače (Windows.Forms, System.Threading a system.timer) je, že jsou pouze přesné dolů na zhruba 10 mili sekund, což je vzhledem k naplánování akce postavené na .NET věřím. (Mluvím o .NET 2 zde). Toto nebylo přijatelné pro mě, a tak jsem musel použít multimediální časovače (je třeba importovat dll). Také jsem napsal třídu obálky pro všechny časovače, takže můžete přepínat mezi nimi v případě potřeby s použitím minimální změny kódu. Podívejte se na můj blog post zde: http://www.indigo79.net/archives/27

Odpovězeno 11/02/2011 v 11:09
zdroj uživatelem

hlasů
1

Co je C ++ aplikace používáte? Můžete použít vždy stejnou věc, nebo zabalit kód časovače z C ++ do C ++ / CLI třídě.

Odpovězeno 12/08/2008 v 14:17
zdroj uživatelem

hlasů
0

System.Windows.Forms.Timer je omezen na přesnost 55 milisekund ...

Odpovězeno 04/10/2010 v 04:30
zdroj uživatelem

hlasů
0

Třídy časovač může začít chovat divně, když je časovač ‚tick‘ code event neskončil provádění v době, kdy dojde k další ‚tick‘. Jeden způsob, jak bojovat s tímto, je zakázat časovač na začátku akce klíštěte, znovu povolit na konci.

Avšak tento přístup není vhodný v případech, kdy je doba provedení o ‚klíštěte‘ Kód není přijatelné chyby v časování klíštěte, protože časovač bude deaktivován (nepočítaje) během této doby.

Pokud zakázání časovač je možnost, pak si můžete také dosáhnout stejného efektu vytvořením samostatné vlákno, které vykonává, spí na dobu x milisekund spustí, spí, atd ...

Odpovězeno 12/08/2008 v 15:09
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more