我要的是删除一个Notification
来自ObservableCollection<Notification>
超时后。有没有比为每个添加的项目和 Thread.Sleep
启动一个新的 ThreadPool 线程更好的方法?在那里?
最终代码基于 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]);
}
}
最佳答案
某种类型的 Timer 不是更合适吗?然后你可以只有一个线程,如果还有更多项目剩余,它将恢复计时器并在一秒钟后再次检查是否是删除下一个通知的时间。
编辑: 由于您使用的是 .net 3.5,我假设使用 DispatcherTimer 的 WPF。据我所知,这将自动使用正确的线程来运行您传递给它的方法。这是未经测试的代码:
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();
}
}
}
关于c# - 超时后从集合中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/688217/