Jun 12 2009

Parallels Extensions for .NET Framework 3.5

Category: zvolkov @ 13:06

Today I had very pleasant experience with new library that Microsoft will ship as part of .NET 4.0. If you want to start playing with it now, it's available as Parallels Extensions for .NET Framework 3.5 and you can easily get it from Microsoft web site. Note that as any other .NET assembly, it does _not_ have to be installed, you can simply drop it alongside your application binaries.

The piece that got me so excited today is called "CountdownEvent" -- this is a synchronization primitive that helps your write elegant multithreaded code.

Consider following example. In order to reproduce a race condition, I need to start two threads at exactly the same time, wait until they're done, and then see if the error happened in one of them. Having two threads wait for an event is trivial with ManualResetEvent. However, traditionally, waiting until both threads are done was a more challenging task, requiring multiple ManualResetEvents, and WaitAll, or, even worse, Monitor and pulsing. This was error prone and required careful testing. 

Now, thanks to the CountdownEvent, you simply start at a number, make your worker threads do .Decrement(), and just do a Wait in your main thread. Bravissimo!

using System;
using System.Threading;
using FileHelpers;
using NUnit.Framework;

namespace FileHelpersTests.Tests.Common
{
    [TestFixture]
    public class Multithreading
    {
        private ManualResetEvent flagStart;
        private CountdownEvent flagFinish;
        private Exception initializationException;

        [Test]
        public void AsyncEngineInitialization()
        {
            flagStart = new ManualResetEvent(false);
            flagFinish = new CountdownEvent(2);

            new Thread(InitializeAsyncEngineWhenFlagIsRaised).Start();
            new Thread(InitializeAsyncEngineWhenFlagIsRaised).Start();

            flagStart.Set();
            flagFinish.Wait();
            
            if (initializationException != null) throw new ApplicationException("Failure during AsyncEngine initialization", initializationException);
        }

        private void InitializeAsyncEngineWhenFlagIsRaised()
        {
            flagStart.WaitOne();
            try
            {
                new FileHelperAsyncEngine<SampleType>();
            }
            catch (Exception e)
            {
                initializationException = e;
            }
            flagFinish.Decrement();
        }

    }
}

Tags:

Comments

Add comment


(Will show your Gravatar icon)

biuquote
  • Comment
  • Preview
Loading