Linq C#如何使ConcurrentQueue根据条件进行清理

Linq C#如何使ConcurrentQueue根据条件进行清理,linq,c#-4.0,concurrent-queue,Linq,C# 4.0,Concurrent Queue,如何使ConcurrentQueue根据第一个元素的条件进行清理。例如,清除旧的博客帖子。我想到了ConditionConcurrentQueue的概念: using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Threading; public class ConditionConcurrentQueue<T> : ConcurrentQue

如何使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);
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.Concurrent;
使用系统线程;
公共类条件ConcurrentQueue:ConcurrentQueue
T:在哪里上课
{
公共条件ConcurrentQueue(Func条件)
:此(空,条件)
{ }
公共条件ConcurrentQueue(IEnumerable items,Func条件)
:基本(项目)
{
_条件=条件;
}
私有函数条件;
公共虚拟空位排队(T项)
{
T去除;
bool cleaningRun=true;
int failedCnt=0;
而(!IsEmpty&&cleaningRun&&failedCnt<10)
{
如果(TryPeek(移出))
{
bool result=_condition.Invoke(已删除);
如果(!结果)
{
如果(!TryDequeue(已移除))
{
失败的CNT++;
睡眠(10);
}
}
其他的
cleaningRun=false;
}
其他的
{
失败的CNT++;
睡眠(10);
}
}
基本。排队(项目);
}
}
使用此条件ConcurrentQueue可以是:

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);
    }
}
class博客
{
公共条件ConcurrentQueue发布{get;set;}
}
班岗
{
公共日期时间{get;set;}
公共字符串文本{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
博客=新博客
{
Posts=新条件ConcurrentQueue(
新职位【】{
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(newpost{Time=DateTime.Now-TimeSpan.FromMinutes(20),Text=“Title 4”});
foreach(在blog.Posts.ToList()中发布帖子)
Console.WriteLine(post.Text);
}
}
也许这是太原始的解决方案。
如有任何改进,我将不胜感激。谢谢。

此外,您还可以通过扩展方法进行尝试:

    public static ICollection<T> Enqueue<T>(this ConcurrentQueue<T> field, T item, Func<T, bool> predicate)
    {
        ICollection<T> removed = field.TryDequeue<T>(predicate);

        field.Enqueue(item);

        return removed;
    }

    public static ICollection<T> TryDequeue<T>(this ConcurrentQueue<T> field, Func<T, bool> predicate)
    {
        T comparedItem;
        var removedList = new List<T>();

        while (field.TryPeek(out comparedItem))
        {
            if (!predicate.Invoke(comparedItem))
            {
                if (field.TryDequeue(out comparedItem))
                    removedList.Add(comparedItem);
                else
                    break;
            }
            else
                break;
        }

        return removedList;
    }
公共静态ICollection排队(此ConcurrentQueue字段、T项、Func谓词)
{
ICollection removed=field.TryDequeue(谓词);
字段。排队(项目);
移除返回;
}
公共静态ICollection TryDequeue(此ConcurrentQueue字段,Func谓词)
{
T比较它们;
var removedList=新列表();
while(field.TryPeek(out comparedItem))
{
if(!predicate.Invoke(comparedItem))
{
if(field.TryDequeue(out comparedItem))
removedList.Add(comparedItem);
其他的
打破
}
其他的
打破
}
返回删除列表;
}

此外,您还可以通过扩展方法进行尝试:

    public static ICollection<T> Enqueue<T>(this ConcurrentQueue<T> field, T item, Func<T, bool> predicate)
    {
        ICollection<T> removed = field.TryDequeue<T>(predicate);

        field.Enqueue(item);

        return removed;
    }

    public static ICollection<T> TryDequeue<T>(this ConcurrentQueue<T> field, Func<T, bool> predicate)
    {
        T comparedItem;
        var removedList = new List<T>();

        while (field.TryPeek(out comparedItem))
        {
            if (!predicate.Invoke(comparedItem))
            {
                if (field.TryDequeue(out comparedItem))
                    removedList.Add(comparedItem);
                else
                    break;
            }
            else
                break;
        }

        return removedList;
    }
公共静态ICollection排队(此ConcurrentQueue字段、T项、Func谓词)
{
ICollection removed=field.TryDequeue(谓词);
字段。排队(项目);
移除返回;
}
公共静态ICollection TryDequeue(此ConcurrentQueue字段,Func谓词)
{
T比较它们;
var removedList=新列表();
while(field.TryPeek(out comparedItem))
{
if(!predicate.Invoke(comparedItem))
{
if(field.TryDequeue(out comparedItem))
removedList.Add(comparedItem);
其他的
打破
}
其他的
打破
}
返回删除列表;
}

从.NET Core 2.0/.NET Standard 2.1/.NET Framework 5.0开始,在
ConcurrentQueue上有一个
Clear()
方法。请参阅:.

自.NET Core 2.0/.NET Standard 2.1/.NET Framework 5.0起,
ConcurrentQueue
上有一个
Clear()
方法。请参阅: