10 秒内不再重试的 BlockingCollection
BlockingCollection that doesn't try again within 10 seconds
我正在使用Blockingcollection
作为FIFO queue
但是我对文件做了很多操作,其中consumer
可能很容易遇到文件锁定,所以我有done 创建了一个简单的 try catch,其中消费者重新排队,但是在队列中有很多其他项目的长 FIFO queue
中,这足以暂停,但在空的或非常短的 FIFO queue
这意味着 consumer
不断地通过自身重复出现来敲击队列,这些事件可能仍会被文件锁定。
即
consumer busy
-> 重新排队 -> consumer busy
-> 重新排队(无限次)
有没有办法让 BlockingCollection
不尝试 运行 新消费者,如果它不到 10 秒?也就是说,如果 createdDateTime 为 null(第一次尝试的默认值)或者大于 10 秒,则可能会在队列中获得净值并继续,并且只接受下一个消费者?
没有任何内置的东西可以帮助解决这个问题。与每个工作项一起存储上次尝试时的 DateTime
(如果这是第一次尝试,则可以是 null
)。然后,在您的处理函数中等待 TimeSpan.FromSeconds(10) - (DateTime.UtcNow - lastAttemptDateTime)
秒,然后再进行下一次尝试。
考虑切换到优先级队列,该队列按最早下一次尝试日期时间的顺序存储项目。
您可以保留两个阻塞集合:主要集合和 "delayed" 集合。一个工作线程只会在延迟的线程上工作,将它们读到主集合中。被拒绝集合的签名类似于:
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);
}
}
}
我正在使用Blockingcollection
作为FIFO queue
但是我对文件做了很多操作,其中consumer
可能很容易遇到文件锁定,所以我有done 创建了一个简单的 try catch,其中消费者重新排队,但是在队列中有很多其他项目的长 FIFO queue
中,这足以暂停,但在空的或非常短的 FIFO queue
这意味着 consumer
不断地通过自身重复出现来敲击队列,这些事件可能仍会被文件锁定。
即
consumer busy
-> 重新排队 -> consumer busy
-> 重新排队(无限次)
有没有办法让 BlockingCollection
不尝试 运行 新消费者,如果它不到 10 秒?也就是说,如果 createdDateTime 为 null(第一次尝试的默认值)或者大于 10 秒,则可能会在队列中获得净值并继续,并且只接受下一个消费者?
没有任何内置的东西可以帮助解决这个问题。与每个工作项一起存储上次尝试时的 DateTime
(如果这是第一次尝试,则可以是 null
)。然后,在您的处理函数中等待 TimeSpan.FromSeconds(10) - (DateTime.UtcNow - lastAttemptDateTime)
秒,然后再进行下一次尝试。
考虑切换到优先级队列,该队列按最早下一次尝试日期时间的顺序存储项目。
您可以保留两个阻塞集合:主要集合和 "delayed" 集合。一个工作线程只会在延迟的线程上工作,将它们读到主集合中。被拒绝集合的签名类似于:
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);
}
}
}