我需要在添加后几秒钟从列表中删除项目。我现在有一个ObservableCollection,我在其中添加了一些消息。我需要将它们删除,让我们说它们被添加后5秒。我试图创建一个负责添加项目和设置计时器的函数:
public void AddInfoItem(string info)
{
infoList.Add(info);
Timer newTimer = new Timer(5000);
newTimer.Elapsed += new ElapsedEventHandler(this.TimerFunction);
newTimer.Enabled = true;
newTimer.Start();
}
public void TimerFunction(Object sender, EventArgs e)
{
infoList.Clear();
}
我甚至没有发送任何参数,应该删除哪个项目导致第二个函数引发异常。有人可以描述一个适当的解决方案来添加项目并在一段时间后删除它吗?
Sory因为没有早点写出来。
是个例外此类集合视图不支持从与调度程序线程不同的线程更改其sourcecollection
答案 0 :(得分:1)
如果在WPF中工作,请使用DispatcherTimer。我通常使用这样的东西:
public static void Delay(int milliseconds, Action action)
{
var t = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(milliseconds) };
t.Tick += (o, e) => { t.Stop(); action.Invoke(); };
t.Start();
}
DispatcherTimer将确保在同一个线程上调用该事件,这样您就不会遇到线程问题。另一种方法是使您绑定到线程安全的集合。但实际上,知道你收到的异常而不是猜测会更容易。
此外,如果您快速连续添加和删除大量项目或要求您的时间准确,您需要考虑其他事项; DispatcherTimer不是很精确,并且确实带来了一些开销,因此很多实例会消耗一些资源。
答案 1 :(得分:1)
而是从计时器列表中删除项目,为什么不在每个项目添加时存储过期时间,只在需要检索项目或迭代列表时忽略或删除过期项目?
答案 2 :(得分:0)
听起来像Reactive Extensions的工作。这里是a link到101 Rx样本,向您展示如何开始。
基本上你想做什么(部分伪代码)
Observable
.FromEvent<NotifyCollectionChangedEventArgs>(infoList, "CollectionChanged")
.Where(args => args.Action == NotifyCollectionChangedAction.Add)
.Delay(TimeSpan.FromSeconds(5))
.ObserveOnDispatcher()
.Subscribe(args => infoList.Remove(args.NewItems));
只要您在完成后处理Subscribe方法返回的IDisposable,就不需要处理定时器和泄漏。
修改强>
无耻的自我插件 - 我用一个工作的控制台应用程序示例做了blog post。您将拥有的一个区别是,您希望在您的WPF应用中保留ObserverOnDispatcher()
电话,否则您将遇到一些线程错误。
答案 3 :(得分:0)
根据Bryan上面的回答,这里是你如何通过ReactiveXaml的ReactiveCollection,ObservableCollection的扩展来实现的:
theCollection.ItemsAdded
.Delay(TimeSpan.FromSeconds(5))
.Subscribe(theCollection.Remove);
答案 4 :(得分:-2)
确保您的垃圾收集器没有丢弃您的infoList。尝试GC.KeepAlive(infoList)