0

I want a list that would hold a item for a specified time.
This is what I tried for now:

private void digtimer_Tick(object sender, EventArgs e) //Goes off every half a second
{
    justmine.Clear();
}

However, this way deletes all of the items after every interval, regardless of how long the items in the list existed. Is there any way so that after an list item exists for a specified time, it is removed?

EDIT: The list is integers only. The newest code is:

` //public static Dictionary<int, DateTime> justmine = new Dictionary<int, DateTime>();
//Adding an item is: justmine.Add(userid, DateTime.Now);
private void digtimer_Tick(object sender, EventArgs e)
    {
        foreach (KeyValuePair<int, DateTime> pair in justmine)
        {
            console.Items.Add((DateTime.Now - pair.Value).TotalSeconds).ToString();
                string x = ((DateTime.Now - pair.Value).TotalSeconds).ToString();
            if ((Convert.ToDouble(x) < 500.0))
            {
                justmine.Remove(pair.Key);
            }
        }
    }
`

This would of seemed to work, but I am not able to edit the dictionary while the tick is running. EXTRA NOTE This list is now a Dictionary with

public static Dictionary<int, DateTime> justmine = new Dictionary<int, DateTime>();
  • 1
    You could store items as a `Tuple` and then only allow access to items that have not "expired" (in other words, you don't necesarilly need to *remove* the items from the list). – crashmstr Jun 24 '15 at 17:57
  • And one potential problem with really *removing* items is what happens if you are doing a `foreach` over the list and items are removed? (answer: nothing good happens) – crashmstr Jun 24 '15 at 17:59
  • Before you do a foreach, you should copy the list and iterate through the copy. – mdebeus Jun 24 '15 at 18:17

3 Answers3

0

This is a two part answer. For one you need the add time. So add a DateTime to your type called Added. Now when you add an item to the list you need to do;

myInstance.Added = DateTime.UtcNow;
justmine.Add(myInstance);

In your digtimer_Tick method, compare the Added value to DateTime.UtcNow like;

 if ((DateTime.UtcNow - item.Added).TotalSeconds > lifeTime) {
    justmine.Remove(item);
 }

Note, better than my suggestion to modify your type is probably the suggestion to use a Tuple<DatTime, YouType> where item1 is just the added time. Do note that tuples are immutable. In general I like it because any type can be used this way, even primitives.

Second note; in digitimer_Tick you could probably do like justmine.Where(x => (DateTime.UtcNow - x.Added).TotalSeconds > lifeTime) and then remove that set from the original collection rather than using a foreach loop.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • Personally rather than record time added, I prefer when it's due to expire. That way it's simply just a matter of `expires <= DateTime.UtcNow`. – Lloyd Jun 24 '15 at 18:02
  • @Lloyd 6 in one, half a dozen in the other but I do like the idea of having an `expires` property on the item. Somewhat depends on your model though. For many data models/store you already have the last time of write which is why I chose it. – evanmcdonnal Jun 24 '15 at 18:06
0

If you understand type arguments well enough, you can create a class extending List<T>. Hide the Add() method with your own method to:
1. Call base.Add()
2. Call base.Remove() after a certain time (ideally using a Timer. See this thread)

This way you can abstract the work to the class (List) that should be doing the work rather than having a timer doing it.

Edit: As mentioned in a comment, you might also want to consider concurrency/synchronization. There are Collections in System.Collections.Concurrent you might want to consider for what I assume is a multithreaded application you're making. (Note: While this answer does say you should extend List, NEVER try to roll-your-own with concurrency in Collections. Let the resources do that work for you.)

Community
  • 1
  • 1
Rogue
  • 636
  • 8
  • 22
  • 1
    [Do not extend/inherit from List](http://stackoverflow.com/questions/21692193/why-not-inherit-from-listt) – Mephy Jun 24 '15 at 18:05
  • 1
    @Mephy That question is in a much different context. It asks about the logic of extending `List`. In this case it makes sense, because OP wants a List which behaves in a slightly different way, not an entirely different data structure (Which is what was asked about in the linked thread). – Rogue Jun 24 '15 at 18:09
  • List.Add and List.Remove are not virtual, so you cannot override them. See https://msdn.microsoft.com/en-us/library/3wcytfd1(v=vs.110).aspx – Erik Jun 24 '15 at 23:53
  • My bad, hide, not override. – Rogue Jun 25 '15 at 00:00
0
    public class JustMine
{
    public string Value { get; set; }
    public decimal Milliseconds { get; set; }
    public JustMine()
    {
        this.Milliseconds = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond;
    }
}

        List<JustMine> JustMine = new List<JustMine>();
        var now = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond;
        var limit = 5000; // 5 seconds
        foreach(var item in JustMine.ToList())
        {
            if (now - item.Milliseconds >= limit)
            {
                JustMine.Remove(item);
            }
        }
MIKE
  • 1,039
  • 7
  • 24
  • 1
    Some explanation as to what this code does would be very helpful to OP. Blindly copying code is never good, An answer with no explanation encourages this. – Rogue Jun 24 '15 at 18:27
  • Encapsulate all your list values into a viewmodel and couple it with the current timestamp of when the value was created. Your list values now become a list of type JustMine. Inside your digtimer_tick function you loop through your JustMine list and remove any values that were entered x seconds ago. – MIKE Jun 24 '15 at 19:33