c# - 超时后从集合中删除项目

标签 c# multithreading .net-3.5

我要的是删除一个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/

相关文章:

c# - 最小化 FormClose 防止计算机关机

winforms - 如何在 WinForms 中制作无休止的进度条?

c# - 有什么方法可以保留 UIAutomation 元素吗?

c# - Azure服务总线,如何以先进先出的顺序接收 session ? (先进先出)

c - OpenMP - 临界区 + 缩减

java - 插入 "implements Xyz"的最佳位置是什么?抽象类与扩展类

java - 调用 Thread.sleep() 时子进程停止(在 Windows 下的 Java 中)

c# - 检查控件内是否至少有一个文本框不为空

C# 简单的 directX 控件

c# - 如何在 .NET Micro 中将字符串转换为 DateTime 对象?