Yeast

Throughout my blog, you'll see references to code under the Yeast.* namespace.  Yeast is the name of a framework that I've created for my personal use over the years whose purpose is to solve problems for which i could not find a solution in the .NET base class libraries.  As I blog, I'll make reference to content in the Yeast framework so as to clarify the code upon which my blog posts are based.  Sometimes, I'll include just the class metadata if the blog post isn't really about the Yeast class but just uses it.  In other cases, I'll include full source code if it is my intention to explain the Yeast class's capabilities themselves.

Now, the common question: "Why the heck is the framework called Yeast?"  It's a metaphor for adding yeast to bread dough so that it'll rise.  So, by adding Yeast to your software, you'll make it rise too.  Nobody wants a flat app, now do they.  Also, I do my very best not to compete with pre-existing or new solutions to problems and welcome having my Yeast code become obsolete because Microsoft has introduced a solution.  As an example, the original version of this post introduced a class I called BlockingQueue<T> that implemented a thread safe producer-consumer queue.  Thanks to that original post version Stephen Toub turned me on to BlockingCollection<T> which gives me exactly what I need.  I'm ripping out BlockingQueue<T> from Yeast as we speak.  For perpetuity sake, this is what BlockingQueue looks like.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

namespace Yeast.Collections.Generic
{
 // Summary:
 //     Implements a queue which blocks all consumer threads if the queue is empty,
 //     and signals any waiting consumers once data becomes available.
 public class BlockingQueue<T> : IEnumerable<T>, IEnumerable
 {
  // Summary:
  //     THe object used to ensure that the methods herein are thread safe.
  public readonly object SyncRoot;

  public BlockingQueue();
  //
  //
  // Parameters:
  //   capacity:
  //     The maximum capacity of the underlying queue.
  //
  // Exceptions:
  //   System.ArgumentException:
  //     If the capacity specified is less than one, this constructor will fail.
  public BlockingQueue(int capacity);

  // Summary:
  //     Gets the capacity of this instance as specified in the constructor.
  public int Capacity { get; }
  //
  // Summary:
  //     Gets the number of elements currently in the queue.
  public int Count { get; }
  //
  // Summary:
  //     Set when the queue has no elements in it.
  public WaitHandle Empty { get; }
  //
  // Summary:
  //     Set when the queue has reached it's Capacity.
  public WaitHandle Full { get; }

  // Summary:
  //     Removes an element from the queue and returns it. This method will block
  //     if the queue is empty and will unblock once an item has been enqueued.
  //
  // Returns:
  //     An item of type T that is at the front of the queue.
  public T Dequeue();
  //
  // Summary:
  //     Adds an element to the back of the queue.
  //
  // Parameters:
  //   element:
  //     The element to be added to the queue.
  //
  // Remarks:
  //     If the queue is empty prior to this operation, the Empty event will be set.
  //      If the queue reaches its capacity as a result of this operation, the Full
  //     event will be set.
  public void Enqueue(T element);
  //
  // Summary:
  //     Implements an enumerator that internally calls Yeast.Collections.Generic.BlockingQueue<T>.Dequeue()
  //     so as to yield the next elements in the queue.  The resulting enumerator
  //     will behave just as if Dequeue were called in a loop.
  //
  // Returns:
  //     An enumerator that internally dequeues elements from the queue infinitely.
  public IEnumerator<T> GetEnumerator();
 }
}