2010-10-31 35 views
19

Tôi về cơ bản muốn có đối tượng hẹn giờ điều phối chỉ thực hiện một lần.DispatcherTimer đánh dấu một lần

Vì vậy, tôi có mã cơ bản:

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

Sau đó, bên trong sự kiện click:

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

Làm thế nào tôi có thể dừng bộ đếm thời gian hoặc giết chết các đối tượng sau khi thực hiện điều này?

Trả lời

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

Dưới đây là mã thay thế bằng biểu thức lambda:

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

timer.Start(); 
+0

thể không phải là thu gom rác thoát khỏi bộ đếm thời gian trước khi sự kiện cháy? – Cameron

+0

@Cameron, không vì bộ hẹn giờ hiện có tham chiếu đến hàm ẩn danh, do đó không thể thu thập rác. –

+1

Phải, nhưng ai khác có tham chiếu đến chức năng ẩn danh đó? Không thể * mà * cũng được thu thập? – Cameron

2

câu trả lời có thể làm việc ra nhưng bạn nên tách lắng nghe sự kiện của bạn từ sự kiện Tick khi bạn không cần hẹn giờ nữa . Tôi không tin tưởng tổ chức sự kiện và người thu gom rác thải;)

Tôi lấy phân lớp đẹp này của DispatcherTimer để có một lớp convinient cho các bộ đếm thời gian.

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 
} 

Ví dụ:

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

Tín dụng cho câu trả lời của Vlad. –

Các vấn đề liên quan