3

我有一个如下列表:

private List<DateTime> _result = new List<DateTime();

我给它增加了价值,比如

_result.Add(DateTime.Now);

要求是每个添加的项目都应在 5 分钟期限内从列表中删除。

我在想我可以创建一个计时器,它每例如 1 分钟检查一次我的列表并找到旧项目并删除它们,但我希望有一个更简单的方法?

如何实施?

谢谢

4

2 回答 2

5

这是我对此的看法:

public class DateWrapper
{
    private ConcurrentBag<DateWrapper> list;
    private DateTime time;

    public DateTime Time
    {
        get { return time; }
    }

    private Timer timer;

    public DateWrapper(ConcurrentBag<DateWrapper> _list, DateTime _time)
    {
        list = _list;
        time = _time;

        list.Add(this);

        timer = new Timer();
        timer.Interval = 300000; // 5 Minutes
        timer.Tick += new EventHandler(Tick);
        timer.Start();
    }

    private void Tick(object sender, EventArgs e)
    {
        list.Remove(this);
    }
}

以上适用于小项目列表。列表太大,你会得到太多的计时器......并且性能会受到影响。

因此,如果您必须处理很多项目,这是一种通用的方法:

public class ExpirableList<T> : IList<T>
{
    private volatile List<Tuple<DateTime, T>> collection = new List<Tuple<DateTime,T>>();

    private Timer timer;

    public int Interval
    {
        get { return timer.Interval; }
        set { timer.Interval = value; }
    }

    private TimeSpan expiration;

    public TimeSpan Expiration
    {
        get { return expiration; }
        set { expiration = value; }
    }

    /// <summary>
    /// Define a list that automaticly remove expired objects.
    /// </summary>
    /// <param name="_interval"></param>
    /// The interval at which the list test for old objects.
    /// <param name="_expiration"></param>
    /// The TimeSpan an object stay valid inside the list.
    public ExpirableList(int _interval, TimeSpan _expiration)
    {
        timer = new Timer();
        timer.Interval = _interval;
        timer.Tick += new EventHandler(Tick);
        timer.Start();

        expiration = _expiration;
    }

    private void Tick(object sender, EventArgs e)
    {
        for (int i = collection.Count - 1; i >= 0; i--)
        {
            if ((DateTime.Now - collection[i].Item1) >= expiration)
            {
                collection.RemoveAt(i);
            }
        }
    }

    #region IList Implementation
    public T this[int index]
    {
        get { return collection[index].Item2; }
        set { collection[index] = new Tuple<DateTime, T>(DateTime.Now, value); }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return collection.Select(x => x.Item2).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return collection.Select(x => x.Item2).GetEnumerator();
    }

    public void Add(T item)
    {
        collection.Add(new Tuple<DateTime, T>(DateTime.Now, item));
    }

    public int Count
    {
        get { return collection.Count; }
    }

    public bool IsSynchronized
    {
        get { return false; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public void CopyTo(T[] array, int index)
    {
        for (int i = 0; i < collection.Count; i++)
            array[i + index] = collection[i].Item2;
    }

    public bool Remove(T item)
    {
        bool contained = Contains(item);
        for (int i = collection.Count - 1; i >= 0; i--)
        {
            if ((object)collection[i].Item2 == (object)item)
                collection.RemoveAt(i);
        }
        return contained;
    }

    public void RemoveAt(int i)
    {
        collection.RemoveAt(i);
    }

    public bool Contains(T item)
    {
        for (int i = 0; i < collection.Count; i++)
        {
            if ((object)collection[i].Item2 == (object)item)
                return true;
        }

        return false;
    }

    public void Insert(int index, T item)
    {
        collection.Insert(index, new Tuple<DateTime, T>(DateTime.Now, item));
    }

    public int IndexOf(T item)
    {
        for (int i = 0; i < collection.Count; i++)
        {
            if ((object)collection[i].Item2 == (object)item)
                return i;
        }

        return -1;
    }

    public void Clear()
    {
        collection.Clear();
    }
    #endregion
}
于 2012-11-07T09:25:40.903 回答
0

您可以使用后台线程,它将遍历列表并删除不需要的元素。

public void RemoveDates()
        {
            var checkDatesTask= new Task(
                () =>
                    {
                        while (!_cancelationTokenSource.IsCancellationRequested)
                        {
                            //TODO: check and delete elements here

                            _cancelationTokenSource.Token.WaitHandle.WaitOne(
                                TimeSpan.FromSeconds(
                                   5));
                        }
                    },
                _cancelationTokenSource.Token,
                TaskCreationOptions.LongRunning);
            checkDatesTask.Start();
        }

ps 我建议您阅读有关异步的更多信息。操作。

于 2012-11-07T09:23:59.350 回答