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秒,则只采取下一个消费者?
没有内置的帮助。在每个工作项最后一次尝试时存储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);
}
}
}