BlockingCollection在10秒内没有重试

本文关键字:重试 10秒 BlockingCollection | 更新日期: 2023-09-27 17:49:30

我使用Blockingcollection作为FIFO queue,但我在文件上做了很多操作,其中consumer可能很容易遇到文件锁,所以我所做的是创建一个简单的尝试捕获,消费者重新队列本身,但在长FIFO queue中有许多其他项目在队列中这是足够的暂停,但在一个空的或非常短的FIFO queue中,这意味着consumer会不断地重复出现在队列中,这可能仍然是文件锁定的。

consumer busy ->请求队列-> consumer busy ->请求队列(ad infinite)

是否有一种方法可以让BlockingCollection不尝试运行新消费者,如果它少于10秒的时间?即潜在地获得队列中的净一个并继续,如果它的createdDateTime为null(第一次尝试的默认值)或如果它> 10秒,则只采取下一个消费者?

BlockingCollection在10秒内没有重试

没有内置的帮助。在每个工作项最后一次尝试时存储DateTime(如果这是第一次尝试,可以是null)。然后,在处理函数中等待TimeSpan.FromSeconds(10) - (DateTime.UtcNow - lastAttemptDateTime)秒,然后再进行下一次尝试。

考虑切换到按最早的下一次尝试日期时间顺序存储项的优先级队列。

可以保留两个阻塞集合:主集合和"延迟"集合。一个工作线程只处理延迟的线程,将它们读入主集合。被拒绝集合的签名类似于:

BlockingCollection<Tuple<DateTime, YourObject>>

现在…如果时间固定为10秒,延迟的收集将几乎被DateTime排序(在几乎同时添加的项目的情况下,这可能是不正确的,但我们说的是毫秒差…没问题)

public class MainClass
{
    // The "main" BlockingCollection
    // (the one you are already using)
    BlockingCollection<Work> Works = new BlockingCollection<Work>();
    // The "delayed" BlockingCollection
    BlockingCollection<Tuple<DateTime, Work>> Delayed = new BlockingCollection<Tuple<DateTime, Work>>();
    // This is a single worker that will work on the Delayed collection
    // in a separate thread
    public void DelayedWorker()
    {
        Tuple<DateTime, Work> tuple;
        while (Delayed.TryTake(out tuple, -1))
        {
            var dt = DateTime.Now;
            if (tuple.Item1 > dt)
            {
                Thread.Sleep(tuple.Item1 - dt);
            }
            Works.Add(tuple.Item2);
        }
    }
}