Laden...

Waitable Timer

Erstellt von Floste vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.379 Views
Floste Themenstarter:in
1.130 Beiträge seit 2007
vor 14 Jahren
Waitable Timer

Beschreibung:

Ich habe schon öfters einen waitable-timer im framework vermisst: das ist ein timer ohne callback, genauer gesagt ein waithandle, das sich periodisch wieder setzt.

leider hat sich herausgestellt, dass er die für wait- und threadingfunktionen typische genauigkeit von 15,3 ms hat. Wenn man also 23ms einstellt wird abwechselnd 15,3 und 30,6 ms gewartet. Die genauen Zeiten können natürlich von Pc zu pc variieren.
Vorteile sind, dass das Interval nicht von der Länge der Verarbeitung abhängt, kein neuer thread erzeugt wird und man sehr genau steuern kann, wann gewartet wird und wann nicht. Wenn man weniger oft wartet als der timer auf signalisiert steht, wird der timer trotzdem nur einfach gesetzt. Es stapelt sich nichts an. Man kann außerdem den timer wie ein gewöhnliches EventWaitHandle benutzen und waithandle.waitany und waithandle.waitall benutzen.

Man kann sowohl einmalig alsauch sofort alsauch periodisch auslösen.

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace General
{
    public class WaitableTimer:WaitHandle
    {
        public WaitableTimer(Mode mode)
        {
            Handle= CreateWaitableTimerEx(IntPtr.Zero,null,mode, SynchronizationObjectSecurity.TIMER_ALL_ACCESS);
        }

        [DllImport("kernel32.dll")]
        static extern bool CloseHandle(IntPtr hHandle);

        [DllImport("kernel32.dll")]
        static extern IntPtr CreateWaitableTimerEx(IntPtr lpTimerAttributes, [MarshalAs(UnmanagedType.LPStr),In]string lpTimerName,Mode dwFlags,SynchronizationObjectSecurity dwDesiredAccess);
        
        [DllImport("kernel32.dll")]
        [return:MarshalAs( UnmanagedType.Bool)]
        static extern bool CancelWaitableTimer(IntPtr hTimer);
        
        [DllImport("kernel32.dll",SetLastError=true)]
        [return:MarshalAs( UnmanagedType.Bool)]
        static extern bool SetWaitableTimer(IntPtr hTimer,ref long pDueTime,int lPeriod,
            IntPtr pfnCompletionRoutine,IntPtr lpArgToCompletionRoutine,[MarshalAs( UnmanagedType.Bool)] bool fResume);

        [DllImport("kernel32.dll",SetLastError=true)]
        [return:MarshalAs( UnmanagedType.Bool)]
        static extern bool ResetEvent(IntPtr handle);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetEvent(IntPtr handle);


        public void SetTimeout(int start,int period)
        {
            SetTimeout(start,period,false);
        }

        public void SetTimeout(int start,int period,bool wake)
        {
            long startDelay=-start*10000L;//1 ms=10000*100ns
            SetWaitableTimer(Handle,ref startDelay,period,IntPtr.Zero,IntPtr.Zero,wake);
        }

        public void Stop()
        {
            CancelWaitableTimer(Handle);
        }

        public bool Set()
        {
            return SetEvent(Handle);
        }

        public bool ReSet()
        {
            return ResetEvent(Handle);
        }

        public enum Mode
        {
            Automatic=0,
            Manual=1,
        }

        protected override void Dispose(bool explicitDisposing)
        {
            CloseHandle(Handle);
            Handle = IntPtr.Zero;
        }

        [Flags()]
        public enum SynchronizationObjectSecurity:uint
        {
            DELETE = unchecked((uint)(0x00010000L)),
            READ_CONTROL =unchecked((uint)(0x00020000L)),
            SYNCHRONIZE =unchecked((uint)(0x00100000L)),
            EVENT_MODIFY_STATE=(0x0002),
            TIMER_ALL_ACCESS=(0x1F0003),
            TIMER_MODIFY_STATE=(0x0002),
            TIMER_QUERY_STATE=(0x0001),
        }
    }
}

Schlagwörter: waitable timer object implementation wrapper for c# .net framework

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!