C# 的 FIFO 队列改进

FIFO Queue improvement for C#

嗨,我正在做一项任务,我应该实现一个队列来处理等待处理的作业(生产者-消费者问题)。我必须开发一个比 FIFO 队列工作效率更高的更好的队列。有一些参数描述饥饿发生前的等待时间,队列结束后他们需要处理的时间。消费者在指定的时间来,可以等待指定的时间,轮到他们时,他们会花一些时间来执行他们想做的任何事情。你能帮我用一个更好的队列而不是 FIFO 方法吗?

首先你同时尝试解决不同的问题,如果你想提高常规队列的性能,你可以实现一个基于元素(堆)优先级的队列,如果你想要保持常规队列的优先级,您可以根据整数设置优先级,每次将元素添加到堆中时增加该数字。

我在这里附上我在 google 上找到的第一个 link Priority queue. The order of the insertion is O(log n) if you use a Binary Heap

现在如果你想实现允许并发的队列,你需要隔离公共资源(例如堆存储元素的基本结构)。

Albahari 是一个很好的参考,可以了解生产者-消费者如何处理并发。

下面是您可以用来实现生产者-消费者并发的所有 类 Concurrency sheet

我正在使用其中一种类型添加示例

 //BlockingCollection with a fix number of Products to put, it works with 10 items max on the collection
    class Program
    {
        private static int counter = 1;
        private static BlockingCollection<Product> products =
            new BlockingCollection<Product>(10);

        static void Main(string[] args)
        {
            //three producers
            Task.Run(() => Producer());
            Task.Run(() => Producer());
            Task.Run(() => Producer());

            Task.Run(() => Consumer());

            Console.ReadLine();
        }

        static void Producer()
        {
            while (true)
            {
                var product = new Product()
                {
                    Number = counter,
                    Name = "Product " + counter++
                };

                //Adding one element
                Console.WriteLine("Producing: " + product);
                products.Add(product);

                Thread.Sleep(2000);
            }
        }

        static void Consumer()
        {
            while (true)
            {
                //wait until exist one element
                if (products.Count == 0)
                    continue;

                var product = products.Take();
                Console.WriteLine("Consuming: " + product);

                Thread.Sleep(2000);
            }
        }
    }

    public class Product
    {
        public int Number { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }