Feedback

C# - DelayedEventHandler

Veröffentlicht von am 8/11/2010
(2 Bewertungen)
Hilfklasse, um auf Ereignisse zeitverzögert reagieren zu können. Vergleichbar mit einer Entprellung von elektrischen Signalen.

Beispiel anhand dem SelectedIndexChanged Ereignisses einer Combobox:

this.cmb_Test = new ComboBox();
this.cmb_Test.SelectedIndexChanged += new DelayedEventHandler(5000, new EventHandler(this.egC_GlassCombobox1_SelectedIndexChanged)).OnDelay;
/// <summary>
/// Helper class to call a function delayed
/// </summary>
public class DelayedEventHandler
{
        /// <summary>
        /// Delay-Timer
        /// </summary>
        private Timer t_Delay = new Timer();

        /// <summary>
        /// Delegate that should be invoked  after delay
        /// </summary>
        private EventHandler eventDelegate;

        /// <summary>
        /// Delegate that receive the outer event to start delay
        /// </summary>
        public EventHandler OnDelay;

        /// <summary>
        /// The sender which raised the outer event
        /// </summary>
        private object sender;

        /// <summary>
        /// The event args that comes from the outer event
        /// </summary>
        private EventArgs e;

        /// <summary>
        /// Inits the delayed eventhandler
        /// </summary>
        /// <param name="delay">the time to wait before event is raised in ms</param>
        /// <param name="eventDelegate">the delegate that should be invoked after delay</param>
        public DelayedEventHandler(int delay, EventHandler eventDelegate)
        {

            t_Delay.Interval = delay;
            t_Delay.Tick += new EventHandler(t_Delay_Tick);
            
            this.eventDelegate = eventDelegate;

            //bind delegate to register function, that start delay timer
            this.OnDelay = new EventHandler(this.Register);
        }


        /// <summary>
        /// The time to wait before event is raised in ms
        /// </summary>
        public int Delay
        {
            get { return this.t_Delay.Interval; }
            set { this.t_Delay.Interval = value; }
        }


        private bool stopAndRestart = true;

        /// <summary>
        /// Controls the delay behaviour
        /// </summary>
        public bool StopAndRestart
        {
            get { return stopAndRestart; }
            set { stopAndRestart = value; }
        }
   


        /// <summary>
        /// method invoked after delay
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void t_Delay_Tick(object sender, EventArgs e)
        {
            //stop timer
            this.t_Delay.Stop();

            //invoke outer function by delegate with right sender and eventargs
            if (this.eventDelegate != null)
                this.eventDelegate(this.sender, this.e);
        }

        /// <summary>
        /// invoked when outer event is raised
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Register(object sender, EventArgs e)
        {
            this.sender = sender;
            this.e = e;

            if (this.StopAndRestart)
            {
                //stop and restart timer
                this.t_Delay.Stop();
            }

            this.t_Delay.Start();
        }
Abgelegt unter delay, event, event handling, events, invoke, timer, helper.

8 Kommentare zum Snippet

Rainer Hilmer schrieb am 8/11/2010:
Ich verstehe den Sinn dieses Snippets nicht. Wer möchte nach Auswahl eines Items aus einer ComboBox 5 Sekunden warten bis etwas passiert?
Ausserdem: ich bin kein Elektriker. Was versteht man unter "Entprellung von elektrischen Signalen"?
Thomas Freudenberg schrieb am 8/11/2010:
"Prellen" hast Du manchmal bei Schaltern, wenn der Kontakt nicht sofort schließt, sondern, nun, prellt. Schau einfach mal bei Wikipedia: http://de.wikipedia.org/wiki/Prellen

Das hier vorgestellte DelayedEvent hilft Dir zum Beispiel bei einer Suchmaske. Während Du den Suchbegriff eingibst, läuft schon mal die Suche los. Aber wenn Du schnell tippst, soll nicht nach jedem Zeichen sofort losgesucht werden, sondern erst, wenn Du für eine Sekunde keine Taste mehr gedrückt hast.
Dominik Wagner schrieb am 8/11/2010:
Das Beispiel für den Einsatz ist vielleicht etwas unpassend... das gebe ich zu ;-)

ein realistischeres Beispiel hat Thomas bereits erwähnt...

ein weiteres wäre bspw. wenn du auf ein Resize-Ereignis andere Berechnungen durchführen musst -> dies würde ja ohne "Verzögerung" sehr oft passieren...

ich programmiere auch viele Oberflächen für Touchpanels im Automatisierungssektor -> habe es auch schon erlebt, dass der Touch mehrere Click-Events auslöst wenn der Anwender länger auf dem Button drauf bleibt...

ich hoffe jetzt ist der Sinn des Snippets etwas verständlicher
Jan Welker schrieb am 8/11/2010:
Zu diesem Thema ist der Event-Filter Snippet von Roland Weigelt einen Blick wert: http://dotnet-snippets.de/dns/eventfilter-SID743.aspx
Dort gibt es auch eine ausführliche Erklärung zum Thema.
Dominik Wagner schrieb am 8/11/2010:
Danke für den Hinweis! Hmm wenn ich's früher gewusst hätte, hätte ich mir die Arbeit sparen können...

mein Anliegen war aber auch eine sehr einfache Verwendung (am besten in einer Zeile verwendbar) -> eine generische Klasse für generische Events kann gerne auch noch posten...
Dominik Wagner schrieb am 8/24/2010:
würde sich über eine bewertung freuen ;-)
System.ArgumentException schrieb am 11/7/2015:
Microsoft hat übrigens eine eigene Bibliothek um Events zusammenzufassen bzw. zu throtteln..
http://rx.codeplex.com

Ist auch als NuGet Package erhältlich:
https://www.nuget.org/packages/Rx-Main/
diub schrieb am 11/8/2015:
Die Zeile
private Timer t_Delay = new Timer ();

steht wohl für
private System.Windows.Forms.Timer t_Delay = new System.Windows.Forms.Timer ();

was leider meiner Erfahrung nach bedeutet, das das Ganze nicht funktioniert, wenn keine 'Form' existiert. Also zum Beispiel nicht nutzbar bei Konsolenanwendungen oder gar Diensten.

Und der Compiler meckert nicht mal. Es klappt nur nicht.

Mit 'System.Timers.Timer' oder 'System.Threading.Timer' sollte das Problem zu umgehen sein.


 

Logge dich ein, um hier zu kommentieren!