BlockingCollection不会在10秒内再次尝试

时间:2015-05-18 12:17:39

标签: c# multithreading fifo blockingcollection

我使用Blockingcollection作为FIFO queue,但我对文件进行了大量操作,其中consumer可能很容易遇到文件锁定,所以我所做的就是创建了一个简单的try catch,消费者在其中重新排队,但是在队列中有很多其他项目的长FIFO queue中这已经足够暂停,但是在空的或非常短的FIFO queue它意味着consumer永远会对队列进行重复操作,重复出现可能仍会被文件锁定的重复事件。

consumer busy - >重新排队 - > consumer busy - >重新排队(ad infinitum)

有没有办法让BlockingCollection在不到10秒的时间内不尝试运行新的消费者?即,可能在队列中获取网络并继续进行,并且如果它的createdDateTime为空(第一次尝试的默认值)或者如果它是> 10秒钟?

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

你可以保留两个阻止集合:主要集合和#34;延迟"一。一个工作线程只适用于延迟的线程,将它们读入主集合。被拒绝集合的签名类似于:

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);
        }
    }
}