我正在使用SignalR构建示例项目。我的想法是,我有3个不同的屏幕来显示视频,每隔4秒钟屏幕就会随机变化,并将屏幕ID,视频ID和时间戳保存为IEnumerable列表中的对象。我希望列表仅存储最近的10个更改,因此,如果在第一个位置存储了新的更改,则需要删除最旧的元素;由于有多个屏幕可以更改列表,因此消除方法不能仅限于删除列表的最后一个元素,因此两个屏幕可以同时向列表中添加内容,并且列表的大小更改为12个以上。
如何删除超过10个更改限制的列表中的所有元素?
这是与列表相关的代码。
private readonly ConcurrentDictionary<string, Cambio> _cambios = new
ConcurrentDictionary<string, Cambio>();
var cambios = new List<Cambio>
{
new Cambio{pantalla = "Sin cambios", video= "Sin cambios",
tStamp = DateTime.Now}
//Sample
};
cambios.ForEach(cambio =>
_cambios.TryAdd(cambio.tStamp.ToString(), cambio));
public class Cambio
{
public string pantalla { get;set;}
public string video { get; set; }
public DateTime tStamp { get; set; }
}
答案 0 :(得分:0)
我建议您使用Skip()和Take()方法来做到这一点。
示例:
IEnumerable<int> data = new List<int>() { 1, 2, 3, 4 };
IEnumerable<int> newSubset = data.Skip(2).Take(2);
编辑:
如果您位于ForEach内部,则无法修改迭代集合,您将获得CollectionModifiedException,因此您必须将项目投影到新的列表中。
答案 1 :(得分:0)
您可以创建扩展方法:
public static void AddNew<T>(this List<T> l, T item, int maxAmount)
{
l.Add(item);
if (l.Count >= maxAmount)
{
l.RemoveRange(maxAmount, l.Count - maxAmount);
}
}
然后将其应用于您的列表
答案 2 :(得分:0)
您似乎需要优先级队列。 https://en.m.wikipedia.org/wiki/Priority_queue
C#没有内置的C#,但是您可以自己为应用程序创建一个
https://visualstudiomagazine.com/articles/2012/11/01/priority-queues-with-c.aspx?m=1
https://www.codeproject.com/articles/13295/%2fArticles%2f13295%2fA-Priority-Queue-in-C
答案 3 :(得分:0)
我希望列表仅存储最近的10个更改,所以如果有新更改 存储在第一个位置,最旧的元素需要 删除;
您可以使用有限大小的自定义Queue
:
public class FixedSizedQueue<T> : ConcurrentQueue<T>
{
private readonly object syncObject = new object();
public int Size { get; private set; }
public FixedSizedQueue(int size)
{
Size = size;
}
public new void Enqueue(T obj)
{
base.Enqueue(obj);
lock (syncObject)
{
while (base.Count > Size)
{
T outObj;
base.TryDequeue(out outObj);
}
}
}
}
请查看更多详细信息here。
var queue = new FixedSizedQueue<Cambio>(10);
queue.Enqueue(new Cambio
{
pantalla = "Sin cambios",
video= "Sin cambios",
tStamp = DateTime.Now
});
答案 4 :(得分:0)
如果您想每次获取添加到列表中的最后10个元素,都可以这样:
if(lst.Count>10)
lst = lst.ToArray().Reverse().Take(10);
如果您想采用第10个元素,则可以直接Take(10)