At Stackify, we recently blogged about best practices for C# logging. Today, let’s take a look at another useful capability, the C# Queue.
The C# queue is a FIFO queue collection class in the System.Collection namespace. Storing elements in FIFO style (First In, First Out), the C# queue contains elements in precisely the order they were added, with objects added at one end and removed from the opposite end. This is the opposite order of the Stack collection. Both queues and stacks are useful when you need to store information temporarily, such as elements that you discard after retrieving their values.
Not sure if and why you should use queues? Check out our article “Message Queues & You – 12 Reasons to Use Message Queuing.”
CodeProject.com provides an informative discussion of how C# Queue works by explaining that it mimics how a line would be served in a real-life scenario, such as waiting in line to make a bank transaction or to purchase concert tickets. This is a useful comparison for understanding the First In, First Out concept that C# Queue utilizes. By placing elements in a queue, the first element to be placed in the queue is the first element that should be handled, just as the first person in line would be the first person served by a bank.
C# Queues provide the most benefit when you have separate publishers and subscribers. For example, Stackify’s logging libraries use queues. When you log a message, all needed data is collected and then published to an in-memory C# ConcurrentQueue<T>. The project and all the source code is on GitHub if you want to check it out.
public void QueueLogMessage(Models.LogMsg msg) { try { if (msg == null) return; _MessageBuffer.Enqueue(msg); } catch { } }
A separate background process runs on a timer that listens on the queue. We do this to make the library work asynchronously and we can batch up the log messages before they are uploaded to Stackify’s log management system.
C# now implements queues with generic collection classes that provide enhanced type-safety and better performance for storing value types. There’s also no need to box the elements when using a generic collection class. If your program uses .NET Framework version 4 or later, use the generic collection classes in the System.Collections.Concurrent namespace – particularly if you’ll have multiple threads adding or removing items from the collection at the same time. In the case of a Queue, the concurrent thread ConcurrentQueue<T> is what you’re looking for to provide safe multi-thread access.
You can perform several different operations on C# Queue and the elements it contains. The most commonly used operations include:
C# Queue recognizes the null value and also allows duplicate elements.
C# Queue is a handy tool to use when you need to perform actions on a set of objects in a sequence. C# Queue can be used for very simple, straightforward FIFO operational needs or the more complex. With a bit of coding handiwork, you can even configure a priority queue with C#, in which each element is assigned a priority and operations are performed on elements with the highest priority first.
C# Queues can support multiple readers simultaneously. However, even when a collection is synchronized, it can still be modified by other threads, which will cause the enumerator to throw an exception. Generally, enumerating through a collection is not considered a thread-safe procedure. To get around this issue, locking collections during enumeration is recommended to guarantee thread safety. Alternatively, you can catch exceptions thrown by other threads.
As discussed previously, you can also use the ConcurrentQueue class when you need a synchronized, thread-safe queue. Doing so will enable your application to permit reading/writing by multiple threads while eliminating the need to lock a collection.
A variety of methods can be used with C# Queue to perform different operations. In addition to the commonly used Enqueue(), Dequeue(), and Peek(), other methods may include:
This is not an all-inclusive list of the methods you can use with C# Queue but represents a few of the operations you can perform. In addition to these standard methods, there are dozens of extension methods that can perform more advanced operations on the objects in a Queue.
If you would like to be a guest contributor to the Stackify blog please reach out to stackify@stackify.com