C#

时间:2015-11-25 02:44:35

标签: c# queue fifo

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

1 个答案:

答案 0 :(得分:0)

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

这里我附加了我在google上找到的第一个链接 Priority queue。如果您使用Binary Heap

,则插入顺序为O(log n)

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

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