如何使 ConcurrentQueue 被第一个元素的条件清除。例如清除较旧的博客文章。我想出了一个 ConditionConcurrentQueue 的想法:
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading;
public class ConditionConcurrentQueue<T> : ConcurrentQueue<T>
where T: class
{
public ConditionConcurrentQueue(Func<T, bool> condition)
: this(null, condition)
{ }
public ConditionConcurrentQueue(IEnumerable<T> items, Func<T, bool> condition)
: base(items)
{
_condition = condition;
}
private Func<T, bool> _condition;
public virtual void Enqueue(T item)
{
T removed;
bool cleaningRun = true;
int failedCnt = 0;
while (!IsEmpty && cleaningRun && failedCnt < 10)
{
if (TryPeek(out removed))
{
bool result = _condition.Invoke(removed);
if (!result)
{
if (!TryDequeue(out removed))
{
failedCnt++;
Thread.Sleep(10);
}
}
else
cleaningRun = false;
}
else
{
failedCnt++;
Thread.Sleep(10);
}
}
base.Enqueue(item);
}
}
使用这个 ConditionConcurrentQueue 可能是这样的:
class Blog
{
public ConditionConcurrentQueue<Post> Posts { get; set; }
}
class Post
{
public DateTime Time { get; set; }
public string Text { get; set; }
}
class Program
{
static void Main(string[] args)
{
Blog blog = new Blog
{
Posts = new ConditionConcurrentQueue<Post>(
new Post[] {
new Post { Time = DateTime.Now - TimeSpan.FromMinutes(80), Text = "Title 1" },
new Post { Time = DateTime.Now - TimeSpan.FromMinutes(60), Text = "Title 2" },
new Post { Time = DateTime.Now - TimeSpan.FromMinutes(40), Text = "Title 3" },
},
p => p.Time > DateTime.Now - TimeSpan.FromHours(1))
};
blog.Posts.Enqueue(new Post { Time = DateTime.Now - TimeSpan.FromMinutes(20), Text = "Title 4" });
foreach (Post post in blog.Posts.ToList())
Console.WriteLine(post.Text);
}
}
也许这是太原始的解决方案。我将不胜感激任何改进。谢谢。