2009-03-27 6 views
2

Je souhaite supprimer un Notification à partir d'un après un certain délai. Y a-t-il une meilleure façon que de commencer un nouveau thread ThreadPool pour chaque élément ajouté et Thread.Sleep là?Suppression d'un élément d'une collection après un certain délai


code final basé sur réponse de Nidonocu:

public class NotificationCollection : ObservableCollection<Notification> 
{ 
    private readonly DispatcherTimer timer; 

    public NotificationCollection() 
     : this(Application.Current.Dispatcher) 
    { 
    } 

    public NotificationCollection(Dispatcher dispatcher) 
    { 
     this.timer = 
      new DispatcherTimer(DispatcherPriority.DataBind, dispatcher); 
     this.timer.Tick += this.TimerOnTick; 
    } 

    protected override void InsertItem(int index, Notification item) 
    { 
     base.InsertItem(index, item); 
     if (!this.timer.IsEnabled) 
     { 
      this.StartTimer(item); 
     } 
    } 

    private void StartTimer(Notification item) 
    { 
     var timeout = item.Timestamp + item.Timeout - DateTime.UtcNow; 
     if (timeout < TimeSpan.Zero) 
     { 
      timeout = TimeSpan.Zero; 
     } 

     this.timer.Interval = timeout; 
     this.timer.Start(); 
    } 

    private void TimerOnTick(object sender, EventArgs e) 
    { 
     this.timer.Stop(); 

     this.RemoveAt(0); 
     if (this.Count > 0) 
     { 
      this.StartTimer(this[0]); 
     } 
    } 

Répondre

2

Est-ce pas une sorte de minuterie plus approprié? Vous pourriez alors avoir un seul thread qui s'il y avait plus d'éléments restants, il reprendrait le chronomètre et revérifierait une seconde plus tard s'il était temps de retirer la notification suivante.


Edit: Puisque vous êtes dans .net 3.5 Je suppose WPF qui utilise un DispatcherTimer. Cela utilisera automatiquement le thread correct pour exécuter la méthode que vous lui transmettez telle que je la comprends. Voici le code UNTESTED à essayer:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.ObjectModel; 
using System.Windows.Threading; 
using System.Windows; 

namespace WpfApplication1 
{ 
    public class Notification 
    { 
     public DateTime TimeStamp { get; set; } 
    } 

    public class NotificationCollection : ObservableCollection<Notification> 
    { 
     private readonly TimeSpan timeout; 

     private DispatcherTimer timer; 

     public NotificationCollection(TimeSpan timeout) 
      : this(timeout, Application.Current.Dispatcher) { } 

     public NotificationCollection(TimeSpan timeout, Dispatcher dispatch) 
     { 
      this.timeout = timeout; 
      timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, this.Cleanup, dispatch); 
     } 

     protected override void InsertItem(int index, Notification item) 
     { 
      base.InsertItem(index, item); 
      timer.Start(); 
     } 

     private void Cleanup(object o, EventArgs e) 
     { 
      timer.Stop(); 
      // Sanity 
      if (this.Count == 0) 
       return; 

      var deadList = from note in this.Items 
          where note.TimeStamp + this.timeout - DateTime.UtcNow < TimeSpan.Zero 
          select note; 
      foreach (var note in deadList) 
      { 
       this.Remove(note); 
      } 

      if (this.Count > 0) 
       timer.Start(); 
     } 
    } 
} 
+0

Pourriez-vous donner un exemple? Toutes mes tentatives d'utilisation d'un seul thread ont échoué, principalement parce que les éléments doivent être supprimés dans le thread principal. – dtb

+0

Travailler dessus ... – Nidonocu

+0

Merci. Je l'ai modifié un peu et posté le résultat dans la zone de question. – dtb

0

Je ne créerais pas de thread pour chaque objet inséré. Au lieu de cela, je voudrais avoir un seul thread de nettoyage ou utiliser un objet timer. Lorsque le fil se réveille, il peut parcourir la liste en nettoyant les vieux objets.

Je voudrais également contourner l'opérateur d'index et toutes les autres méthodes d'accès pour ne pas autoriser les éléments qui doivent être nettoyés mais qui n'ont pas encore été.

Questions connexes