2010-10-31 9 views
19

Ich möchte grundsätzlich ein Dispatcher-Timer-Objekt nur einmal ausgeführt werden. SoDispatcherTimer Tick einmal

Ich habe den grundlegenden Code:

DispatcherTimer dispatcherTimer = new DispatcherTimer(); 
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick); 
dispatcherTimer.Interval = new TimeSpan(0, 0, 4); 
dispatcherTimer.Start(); 

dann in der Click-Ereignis:

private void dispatcherTimer_Tick(object sender, EventArgs e) 
     { 
      this.Visibility = System.Windows.Visibility.Visible; 
      // Now stop timer execution.. or kill the timer object 
     } 

Wie kann ich den Timer oder abtöten, das Objekt nach dieser Ausführung stoppen?

Antwort

32
private void dispatcherTimer_Tick(object sender, EventArgs e) 
     { 
      this.Visibility = System.Windows.Visibility.Visible; 
      (sender as DispatcherTimer).Stop(); 
     } 
6
private void dispatcherTimer_Tick(object sender, EventArgs e) 
     { 
      this.Visibility = System.Windows.Visibility.Visible; 
      var dispatcherTimer = (DispatcherTimer)sender; 
      dispatcherTimer.Stop(); 
     }  
21

Hier wird alternativer Code mit Lambda-Ausdruck:

var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(4)}; 
timer.Tick += (sender, args) => 
{ 
    this.Visibility = System.Windows.Visibility.Visible; 
    timer.Stop(); 
}; 

timer.Start(); 
+0

konnte nicht der Garbage Collector des Timers vor dem Ereignis ausgelöst wird loszuwerden? – Cameron

+0

@Cameron, nein, weil Timer jetzt auf die anonyme Funktion verweist, daher kann keine Garbage Collections gesammelt werden. –

+1

Richtig, aber wer hat sonst noch einen Hinweis auf diese anonyme Funktion? Könnte das nicht auch gesammelt werden? – Cameron

2

die Antworten erarbeiten könnten, aber Sie sollten Ihren Event Listener aus dem Tick Ereignisse ab, wenn Sie den Timer länger nicht brauchen . Ich traue Eventhandler und dem Müllsammler nicht;)

Ich war diese nette Unterklasse von DispatcherTimer, um eine convinient Klasse für einzelne tick-Timer zu haben.

public class DispatcherTimeout : DispatcherTimer 
{ 
    #region Constructors and Destructors 

    protected DispatcherTimeout(DispatcherPriority priority) 
     : base(priority) 
    { 
    } 

    #endregion 

    #region Public Properties 

    public Action<DispatcherTimeout> Callback { get; set; } 

    #endregion 

    #region Public Methods and Operators 

    /// <summary> 
    /// Instantiates a new DispatcherTimeout and starts it. 
    /// </summary> 
    /// <param name="priority"> 
    /// The dispatcher priority used for the timer. 
    /// </param> 
    /// <param name="duration"> 
    /// The duration. 
    /// </param> 
    /// <param name="callback"> 
    /// The callback which should be called on tick. 
    /// </param> 
    /// <returns> 
    /// An instance of DispatcherTimeout. 
    /// </returns> 
    public static DispatcherTimeout Timeout(DispatcherPriority priority, TimeSpan duration, Action<DispatcherTimeout> callback) 
    { 
     var dispatcherTimeout = new DispatcherTimeout(priority); 
     dispatcherTimeout.Interval = duration; 
     dispatcherTimeout.Callback = callback; 

     dispatcherTimeout.Tick += dispatcherTimeout.HandleTick; 

     dispatcherTimeout.Start(); 

     return dispatcherTimeout; 
    } 

    #endregion 

    #region Methods 

    private void HandleTick(object sender, EventArgs e) 
    { 
     this.Stop(); 
     this.Tick -= this.HandleTick; 

     if (this.Callback != null) 
     { 
      this.Callback(this); 
     } 
    } 

    #endregion 
} 

Beispiel:

DispatcherTimeout.Timeout(
    DispatcherPriority.Normal, 
    TimeSpan.FromSeconds(2.0), 
    timeout => 
    { 
     this.Visibility = System.Windows.Visibility.Visible; 
    }); 
0
/// <summary> 
    /// Fires an action once after "seconds" 
    /// </summary> 
    public static void FireOnce(float seconds, Action onElapsed) 
    { 
     Action detach = null; 
     var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(seconds) }; 

     var handler = new EventHandler((s, args) => 
     { 
      onElapsed(); 
      // Note: When stop is called this DispatcherTimer handler will be GC'd (eventually). There is no need to unregister the event. 
      timer.Stop(); 
      if (detach != null) 
       detach(); 
     }); 
     detach = new Action(() => timer.Tick -= handler); // No need for deregistering but just for safety let's do it. 

     timer.Tick += handler; 
     timer.Start(); 
    } 
+0

Kredit zu Vlads Antwort. –

Verwandte Themen