2015-06-24 2 views
0

Я хочу список, который будет содержать элемент в течение определенного времени.
Это то, что я попытался сейчас:Элемент в списке существует в течение ограниченного времени

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

Однако этот способ удаляет все элементы после каждого интервала, независимо от того, как долго существовали элементы в списке. Есть ли способ, чтобы после того, как элемент списка существует в течение определенного времени, он удаляется?

EDIT: Этот список является целым числом. Самый новый код:

` //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); 
      } 
     } 
    } 
` 

Возможно, это сработало, но я не могу редактировать словарь во время работы тика. EXTRA Примечание Этот список теперь словарь с

public static Dictionary<int, DateTime> justmine = new Dictionary<int, DateTime>(); 
+1

Вы можете хранить предметы, как 'кортежи ", а затем разрешить доступ к элементам, которые не« истекли »(другими словами, вам необязательно * удалить * элементы из списка). – crashmstr

+0

И одна потенциальная проблема с действительно * удалением * элементов - это то, что происходит, если вы делаете 'foreach' над списком и элементы удаляются? (ответ: ничего хорошего не получается) – crashmstr

+0

Перед тем, как сделать foreach, вы должны скопировать список и перебрать копию. – mdebeus

ответ

0

Это две части ответа. Для одного вам нужно добавить время. Поэтому добавьте DateTime к вашему типу с именем Added. Теперь, когда вы добавляете элемент в список, который вам нужно сделать;

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

В вашем методе digtimer_Tick, сравните значение Добавлено в DateTime.UtcNow как;

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

Обратите внимание, лучше, чем мое предложение, чтобы изменить тип, вероятно, предложение использовать Tuple<DatTime, YouType> где item1 только добавленное время. Обратите внимание, что кортежи неизменяемы. В общем, мне это нравится, потому что любой тип можно использовать таким образом, даже примитивы.

Второе примечание; в digitimer_Tick вы, вероятно, можете сделать как justmine.Where(x => (DateTime.UtcNow - x.Added).TotalSeconds > lifeTime), а затем удалить этот набор из исходной коллекции, а не использовать цикл foreach.

+0

Лично, а не записывать добавленное время, я предпочитаю, когда он истекает.Таким образом, это просто вопрос 'expires <= DateTime.UtcNow'. – Lloyd

+0

@ Lloyd 6 в одном, полдюжины в другом, но мне нравится идея иметь свойство 'expires' на элементе. Тем не менее, это зависит от вашей модели. Для многих моделей данных/магазина у вас уже есть последний раз, потому что я выбрал его. – evanmcdonnal

0

Если вы достаточно хорошо понимаете аргументы типа, вы можете создать класс, расширяющий List<T>. Скрыть метод Add() со своим собственным методом на: (. В идеале с помощью таймера См this thread)
1. Вызовите base.Add()
2. Вызов base.Remove() по истечении определенного времени

Таким образом, вы можете абстрактные работы в классе (List), который должен выполнять работу, а не делать таймер.

Редактировать: Как уже упоминалось в комментарии, вы также можете рассмотреть возможность параллелизма/синхронизации. Есть Коллекции в System.Collections.Concurrent, которые вы, возможно, захотите рассмотреть, поскольку я предполагаю, что это многопоточное приложение, которое вы создаете. (Примечание: В то время как этот ответ не делает, что вы должны продлить List, не пытайтесь катить свой собственный с параллелизмом в коллекции Пусть ресурсы сделать эту работу за вас..)

+1

[Не продлевать/наследовать из списка ] (http://stackoverflow.com/questions/21692193/why-not-inherit-from-listt) – Mephy

+1

@Mephy Этот вопрос находится в совершенно другом контексте. Он спрашивает о логике расширения 'List '. В этом случае это имеет смысл, потому что OP хочет, чтобы List, который ведет себя несколько иначе, а не совсем другая структура данных (о чем было сказано в связанном потоке). – RogueCSDev

+0

Список .Add и список .Remove не являются виртуальными, поэтому вы не можете их переопределить. См. Https://msdn.microsoft.com/en-us/library/3wcytfd1(v=vs.110).aspx – Erik

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); 
      } 
     } 
+1

Некоторое объяснение того, что делает этот код, было бы очень полезно для OP. Слепое копирование кода никогда не бывает хорошим, ответ без объяснения этого поощряет. – RogueCSDev

+0

Инкапсулируйте все свои значения списка в режим просмотра и соедините его с текущей меткой времени, когда это значение было создано. Теперь ваши значения списка становятся списком типа JustMine. Внутри функции digtimer_tick вы просматриваете список JustMine и удаляете любые значения, введенные x секунд назад. – MIKE

Смежные вопросы