Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

A .NET Wrapper for the Vista/Server 2008 Condition Variable (New Sychronization Primitive)

3.50/5 (3 votes)
13 Mar 2008CPOL2 min read 1   240  
Vista introduced a new synchronization primitive called the CONDITION_VARIABLE. In this article, I will provide a .NET wrapper (written in C++/CLI) for this primitive and explain how it works.

Introduction

With the release of Windows Vista, Microsoft introduced a new synchronization primitive called the "Condition Variable". In this article, I will explain (badly) the function of the Condition Variable and also provide a .NET wrapper.

Background

Thread synchronization can be a complex and sometimes frustrating task. I embrace anything which comes along and makes the task a little easier. Microsoft did just that, they introduced the Condition Variable. When I saw it, I said, "Awesome! can't wait to use it!". Unfortunately, the functionality is only exposed to the unmanaged world, and I work in a C# shop. So, what's a guy to do? Um.... Write a wrapper leveraging C++/CLI, expose the functionality to the .NET world, and write an article, of course!

Condition Variables Explained

So, what are condition variables anyway? Condition Variables allow a thread to release a lock (CRITICAL_SECTION) and enter a wait state in a single atomic operation. Once the thread is awakened, it immediately requires the previously released lock. The waking of the thread is controlled via the CONDITION_VARIABLE and associated Win32 API functions. For a far better explanation and a list of the Win32 API functions, see MSDN.

Using the Code

The first thing you will notice is that the C++ project contains not one, but two classes. Given that Microsoft does not expose the "Critical Section" functionality (they do, however, provide similar functionality via the System.Threading.Monitor methods), I also had to write a wrapper for Critical Sections because Condition Variables require them.

You will also notice that I named the wrapper class for the "Condition Variable" functionality, "WaitCondition", it just seems to fit the usage pattern better. Anyway, you have the code and can name it whatever you like. Below, you will find the basic pattern for using the classes (I've included a full port of a sample application from the "Using Condition Variables" section of the Vista/Server 2008 SDK):

C++
WaitCondition waitCondition = new WaitCondition();
CriticalSection criticalSection = new CriticalSection();
//Thread 1:
criticalSection.Enter();
//in a single atomic operation, release the critical section
//and sleep (waiting for the condition variable to be signaled
waitCondition.Sleep(criticalSection);
//Thread 2: wake up Thread 1
waitCondition.WakeOne();
//Thread 1:  Once awake, do something....
DoSomething();
//Exit the Critical Section
criticalSection.Exit();
//Don't forget to dispose, or leverage the 'using' statement
//to ensure that the unmanaged CRITICAL_SECTION and
//CONDITION_VARIABLE structures are properly released
waitCondition.Dispose();
criticalSection.Dispose();

Points of Interest

While it is technically okay to use the CriticalSection class in place of the .NET System.Threading.Monitor class, I would recommend against that. I tested this class against the Monitor class, and it's about 60% slower. Unfortunately, there is no means by which to leverage the Monitor class with Condition Variables.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)