Showing posts with label Threading. Show all posts
Showing posts with label Threading. Show all posts

Thursday, January 17, 2013

MoQ - Running tests in Parallel

It may not be accurate to say that MoQ (Quick start intro) is thread safe when running tests in parallel because it appears it is not in other circumstances.  Check out this blog post where they modified the source to fix a threading issue.

However, it appears that MoQ avoids the issue I described in the previous post about how Rhino falls over intermittently when running tests in parallel.  MoQ avoids this by design.  Here's the modified code from  Test1 converted to MoQ:


    [TestClass]
    public class Test1
    {
        [TestMethod]
        public void Test1a()
        {
            var dependency1 = new Mock<IDependency1>();
            var dependency2 = new Mock<IDependency2>();

            dependency1.Setup(m => m.DependentMethod("System.String")).Returns(false);

            dependency2.Setup(m => m.Kind).Returns(TypeKind.Foo);
            dependency2.Setup(m => m.StringProperty).Returns("System.String");

            var target = new TestSubject(dependency1.Object, dependency2.Object);
            Assert.IsFalse(target.SubjectMethod());
            dependency1.VerifyAll();
            dependency2.VerifyAll();
        }

        [TestMethod]
        public void Test1b()
        {
            var dependency1 = new Mock<IDependency1>();
            var dependency2 = new Mock<IDependency2>();

            dependency1.Setup(m => m.DependentMethod("System.String")).Returns(true);

            dependency2.Setup(m => m.Kind).Returns(TypeKind.Foo);
            dependency2.Setup(m => m.StringProperty).Returns("System.String");

            var target = new TestSubject(dependency1.Object, dependency2.Object);
            Assert.IsTrue(target.SubjectMethod());
            dependency1.VerifyAll();
            dependency2.VerifyAll();
        }
   }

These tests pass every time.
Even the updated brute force parallel tests runs ok.
    [TestClass]
    public class Test2
    {
        [TestMethod]
        public void BruteForceTest()
        {
            var threads = new Thread[30];
            for (int i = 0; i < threads.GetUpperBound(0); i++)
            {
                threads[i] = new Thread(this.ThreadAction);
                threads[i].Start();
            }

            for (int i = 0; i < threads.GetUpperBound(0); i++)
            {
                threads[i].Join();
            }
        }

        private void ThreadAction()
        {
            var dependency1 = new Mock<IDependency1>();
            var dependency2 = new Mock<IDependency2>();

            dependency1.Setup(m => m.DependentMethod("System.String")).Returns(false);

            dependency2.Setup(m => m.Kind).Returns(TypeKind.Foo);
            dependency2.Setup(m => m.StringProperty).Returns("System.String");

            var target = new TestSubject(dependency1.Object, dependency2.Object);
            target.SubjectMethod();
        }
    }


Wednesday, January 16, 2013

Rhino Mock - Running tests in parallel - not thread safe

I came across this issue while diagnosing why some unit tests intermittently fail.  It appears to be that Rhino Mock (v3.6.1) is not thread safe.

There does appear to be some chatter on this topic when you google it.  Someone has even customised their own version of the Rhino code to be thread safe here.

First off, hats off to Ayende and crew for creating Rhino mocks its a fantastic premium mocking library that I have enjoyed using.  Back when it was written running tests in parallel was fringe at best.

My environment:

  • MsTest using a .TestSettings file set to run two tests in parallel.
  • Visual Studio 2012 Premium (not that I think this is relevant).
  • 8 core processor.
  • I'm using the Visual Studio Test Runner to run the tests.

The Code:

Full test code that exposes the issue can be downloaded here.

In Test1 you can see both test methods look fine. 

    [TestClass]
    public class Test1
    {
        [TestMethod]
        public void IsTrivialAssociationShouldReturnFalse()
        {
            var dependency1 = MockRepository.GenerateStub<IDependency1>();
            var dependency2 = MockRepository.GenerateStub<IDependency2>();

            dependency1.Stub(m => m.DependentMethod("System.String")).Return(false);

            dependency2.Stub(m => m.Kind).Return(TypeKind.Foo);
            dependency2.Stub(m => m.StringProperty).Return("System.String");

            var target = new TestSubject(dependency1, dependency2);
            Assert.IsFalse(target.SubjectMethod());
        }

        [TestMethod]
        public void IsTrivialAssociationShouldReturnTrue()
        {
            var dependency1 = MockRepository.GenerateStub<IDependency1>();
            var dependency2 = MockRepository.GenerateStub<IDependency2>();

            dependency1.Stub(m => m.DependentMethod("System.String")).Return(true);

            dependency2.Stub(m => m.Kind).Return(TypeKind.Foo);
            dependency2.Stub(m => m.StringProperty).Return("System.String");

            var target = new TestSubject(dependency1, dependency2);
            Assert.IsTrue(target.SubjectMethod());
        }
    }

The problem only seems to manifest when using the same interface type multiple times in the same test class.
When this runs either one of these tests will intermittently fail given the test settings I am using (running 2 or more in parallel).
You'll either get an Assert failure even though clearly it should not.
A few times I got another weird "System.InvalidOperationException: This action is invalid when the mock object is in replay state."

Its more apparent when you throw many threads at it:
    [TestClass]
    public class Test2
    {
        [TestMethod]
        public void BruteForceTest()
        {
            var threads = new Thread[30];
            for (int i = 0; i < threads.GetUpperBound(0); i++)
            {
                threads[i] = new Thread(this.ThreadAction);
                threads[i].Start();
            }

            for (int i = 0; i < threads.GetUpperBound(0); i++)
            {
                threads[i].Join();
            }
        }

        private void ThreadAction()
        {
            var dependency1 = MockRepository.GenerateStub<IDependency1>();
            var dependency2 = MockRepository.GenerateStub<IDependency2>();

            dependency1.Stub(m => m.DependentMethod("System.String")).Return(false);

            dependency2.Stub(m => m.Kind).Return(TypeKind.Foo);
            dependency2.Stub(m => m.StringProperty).Return("System.String");

            var target = new TestSubject(dependency1, dependency2);
            target.SubjectMethod();
        }
    }


I tried solving this by using the old Rhino syntax of declaring a method local repository with no luck.  I also tried creating dedicated fields for all dependencies for each test and initialising them in the constructor, but this didn't work either.

Solution:

I tested a threadsafe modification to Rhino and it resolved the issues shown in the code example. But I didn't test it extensively.  You can find the blog post here and the DLL download here.  I'm not sure if this is a good idea or not.

Another alternative is to place all your mock expectation calls in the ClassInitialise() of the test class and create separate static fields for each dependency for each test.  This ensures that all tests have had their set up done first.  You should not put this code in a TestInitialise() as this will run prior to every test, and what you're after is running the expectation code exactly once.

    [TestClass]
    public class Test3
    {
        private static IDependency1 dependency1a;

        private static IDependency2 dependency2a;

        private static IDependency1 dependency1b;

        private static IDependency2 dependency2b;

        [ClassInitialize]
        public static void ClassInitialise(TestContext context)
        {
            // For Test a
            dependency1a = MockRepository.GenerateStub<IDependency1>();
            dependency2a = MockRepository.GenerateStub<IDependency2>();

            dependency1a.Stub(m => m.DependentMethod("System.String")).Return(false);

            dependency2a.Stub(m => m.Kind).Return(TypeKind.Foo);
            dependency2a.Stub(m => m.StringProperty).Return("System.String");

            // For Test b
            dependency1b = MockRepository.GenerateStub<IDependency1>();
            dependency2b = MockRepository.GenerateStub<IDependency2>();

            dependency1b.Stub(m => m.DependentMethod("System.String")).Return(false);

            dependency2b.Stub(m => m.Kind).Return(TypeKind.Foo);
            dependency2b.Stub(m => m.StringProperty).Return("System.String");
        }

        [TestMethod]
        public void Test3a()
        {
            var target = new TestSubject(dependency1a, dependency2a);
            Assert.IsFalse(target.SubjectMethod());
        }

        [TestMethod]
        public void Test3b()
        {
            var target = new TestSubject(dependency1b, dependency2b);
            Assert.IsFalse(target.SubjectMethod());
        }
    }
Test 3a and 3b will always pass.

You could also use a lock, although this feels a bit dirty in unit testing, its the least amount of code.

So just a word of warning, you will need to be aware of this only if you take advantage of running tests in parallel.

Tuesday, May 29, 2012

Dictionary is not thread safe

No surprises, dictionary is not thread safe.  But what if you're using it with guaranteed unique keys; ie each thread is guaranteed to be accessing it with a key unique to only that thread?

Here's a test:


private static readonly Dictionary<string, string> dictionary = new Dictionary<string, string>();

     public static void Main(string[] args)
        {
            var threads = new List<Thread>();
            for (int threadNumber = 0; threadNumber < 100; threadNumber++)
            {
                int number = threadNumber;
                var thread = new Thread(
                    () =>
                    {
                        for (int index = 0; index < 1000; index++)
                        {
                            Console.WriteLine("Thread" + number + " index " + index);
                            var key = Guid.NewGuid().ToString();
                            dictionary.Add(key, "Value");
                            var dynamicValue = Guid.NewGuid().ToString();
                            dictionary[key] = dynamicValue;
                            Debug.Assert(dictionary[key] == dynamicValue);
                        }
                    });
                threads.Add(thread);
                thread.Start();
            }

            foreach (var thread in threads)
            {
                thread.Join();
            }
        }

So, as you can see, this is creating a bunch of threads that all hammer the dictionary adding and editing and then asserting everything is as it should be. This runs fine with no exceptions. Or does it...

Comment the Console.WriteLine and it no longer runs...


So what is happening here?  As the dictionary gets larger the it will need to change its internal storage to increase its size, when this occurs another thread will either corrupt it or access stale data. So bad news.

The morale of the story is always add a Console.WriteLine before accessing a dictionary. Just kidding. If you think there will be any sort of multi-thread contention use a ConcurrentDictionary instead.  Just simply by thinking each thread accessing the dictionary using a guaranteed unique key will not suffice.

Saturday, May 7, 2011

WCF Asynchronous Services

During a design session the other day someone was asking what are the possibilities for asynchronous calls in WCF.  There are are number of ways to do it, each with different attributes.

  1. When referencing a standard WCF service from the client using the advanced options (of the Visual Studio add service reference dialog) you can generate BeginInvoke and EndInvoke methods. This allows for an "IAsyncResult invocation pattern" (check out MSDN - Invoking synchronous methods asynchronously and good article on Code Project explaining asynchronous calls).  Essentially you pass in a call-back that will be called when the method returns, and they you are able to retrieve the method result from the IAsynResult argument provided. This gives a clientside WCF service consuming developer the option to execute standard synchronous WCF services asynchronously. Great if you do not have control over the service. Also ideal if the expected delay between request and response is not larger than 60 seconds or so.

  2. A standard WCF service can be decorated with IsOneWay=true in the OperationContract attribute. This effectively tells WCF to immediately return the thread back to the caller.  No return values or response is possible from such a service, including exceptions. These are fire and forget style services (sometimes called Document Services).

  3. The most advanced and flexible way is using Callback Contracts. This requires another Contract be defined and specified with the requesting ServiceContract. Also known as Duplex services.  Usually the Operations are also decorated IsOneWay=True, indicating that the calling thread is released back to the client immediately.  These are ideal when writing a publish/subscribe pattern and the response will be sent back to the client at some future point at an unknown time. It could be minutes or hours, or it could generate 100 responses over time for one "subscribe" request. Its almost like an event subscription.  See the MSDN article referenced below for more info.
    *EDIT* I would recommend avoiding using this pattern if possible, a far more robust way of achieving the same results without resorting to Singletons is using MSMQ.  A common way to deal with long-running Duplex services is to make them singletons to be able to store the callbacks.  You can avoid this by create a class to manage the callbacks, but then this class effectively becomes a singleton.  A far simpler pattern is to take advantage of MSMQ.

Its also worth noting that when searching for Asynchronous method and service invocation patterns the Reactive (Rx) framework seems to come up a lot.  This was a framework that was pioneered by a team at Microsoft to "clean-up" code that needs to call methods asynchronously. Its kind of like Linq over Events, and they succeeded in making calling code more elegant.  However it has been superseded by the Task Parallel Library (TPL) in .NET 4, more specifically the Task Factory and associated classes.  Some say this is not so, but essentially in my humble opinion what can be done out of the box in .NET 4 without an extension framework is the best way to go.


References:

Tuesday, January 4, 2011

Customising the Task.Factory Scheduler

I think it is important to be consistent with your design approaches to problems if at all possible. But it would be naive to think that one approach or tool will be best for any problem.  I had a threading issue to solve recently and I have been making heavy use of the new .NET 4 Task Factory in the TPL library.  The problem was that there is one part of the system that must be single threaded and process incoming events in the order they were received.  I was fully prepared to write a message queue or pump (or find one).

I was delighted to find that the Task Factory has the ability to use a custom scheduler.  The scheduler controls when tasks begin and how many threads are available to process incoming tasks.  Perfect. I just needed a single threaded implementation that processes in the same order as they are queued.

Even better, the MSDN documentation includes an article showing you how to do just this.  The custom scheduler takes a constructor argument for number of threads to use in the pool. So in future if there is a change that allows the inclusion of more threads, this will be easy to change.  Also, if I find a better way, I can revert back to the default task factory and its of the same type as the throttled factory, so that would be an easy change too.

Seeing as the Task Factory used by my problem class is the same type as the default factory (just another instance, with a custom scheduler internal field), I can configure StructureMap to deal out the appropriate factory. Pretty cool stuff.

Here's my final code for my scheduler, which is pretty much the same as the MSDN article above, with style changed etc.


using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Provides a task scheduler that ensures a maximum concurrency level while
    /// running on top of the ThreadPool.
    /// Source: http://msdn.microsoft.com/en-us/library/ee789351.aspx
    /// Author: Microsoft 2009
    /// </summary>
    public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
    {
        /// <summary>
        /// The maximum concurrency level allowed by this scheduler.
        /// </summary>
        private readonly int maxDegreeOfParallelism;

        /// <summary>
        /// The list of tasks to be executed.
        /// </summary>
        private readonly LinkedList<Task> tasks = new LinkedList<Task>();

        /// <summary>
        /// Whether the current thread is processing work items.
        /// </summary>
        [ThreadStatic]
        private static bool currentThreadIsProcessingItems;

        /// <summary>
        /// Whether the scheduler is currently processing work items.
        /// </summary>
        private int delegatesQueuedOrRunning;

        /// <summary>
        /// Initializes a new instance of the LimitedConcurrencyLevelTaskScheduler class with the
        /// specified degree of parallelism.
        /// </summary>
        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
        public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
        {
            this.maxDegreeOfParallelism = maxDegreeOfParallelism;

            if (this.maxDegreeOfParallelism < 1)
            {
                throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
            }
        }

        /// <summary>
        /// Gets the maximum concurrency level supported by this scheduler.
        /// </summary>
        public sealed override int MaximumConcurrencyLevel
        {
            get { return this.maxDegreeOfParallelism; }
        }

        /// <summary>
        /// Queues a task to the scheduler.
        /// </summary>
        /// <param name="task">The task to be queued.</param>
        protected sealed override void QueueTask(Task task)
        {
            // Add the task to the list of tasks to be processed.  If there aren't enough
            // delegates currently queued or running to process tasks, schedule another.
            lock (this.tasks)
            {
                this.tasks.AddLast(task);
                if (this.delegatesQueuedOrRunning < this.maxDegreeOfParallelism)
                {
                    ++this.delegatesQueuedOrRunning;
                    NotifyThreadPoolOfPendingWork();
                }
            }
        }

        /// <summary>
        /// Attempts to execute the specified task on the current thread.
        /// </summary>
        /// <param name="task">The task to be executed.</param>
        /// <param name="taskWasPreviouslyQueued">A Boolean denoting whether or not task has previously been queued. If this parameter is True, then the task may have been previously queued (scheduled); if False, then the task is known not to have been queued, and this call is being made in order to execute the task inline without queuing it.</param>
        /// <returns>
        /// Whether the task could be executed on the current thread.
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="task"/> argument is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">The <paramref name="task"/> was already executed.</exception>
        protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
        {
            // If this thread isn't already processing a task, we don't support inlining
            if (!currentThreadIsProcessingItems)
            {
                return false;
            }

            // If the task was previously queued, remove it from the queue
            if (taskWasPreviouslyQueued)
            {
                TryDequeue(task);
            }

            // Try to run the task.
            return TryExecuteTask(task);
        }

        /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
        /// <param name="task">The task to be removed.</param>
        /// <returns>Whether the task could be found and removed.</returns>
        protected sealed override bool TryDequeue(Task task)
        {
            lock (this.tasks) return this.tasks.Remove(task);
        }

        /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
        /// <returns>An enumerable of the tasks currently scheduled.</returns>
        protected sealed override IEnumerable<Task> GetScheduledTasks()
        {
            var lockTaken = false;
            try
            {
                Monitor.TryEnter(this.tasks, ref lockTaken);
                if (lockTaken)
                {
                    return this.tasks.ToArray();
                } else
                {
                    throw new NotSupportedException();
                }
            } finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(this.tasks);
                }
            }
        }

        /// <summary>
        /// Informs the ThreadPool that there's work to be executed for this scheduler.
        /// </summary>
        private void NotifyThreadPoolOfPendingWork()
        {
            ThreadPool.UnsafeQueueUserWorkItem(
                _ =>
                {
                    // Note that the current thread is now processing work items.
                    // This is necessary to enable inlining of tasks into this thread.
                    currentThreadIsProcessingItems = true;
                    try
                    {
                        // Process all available items in the queue.
                        while (true)
                        {
                            Task item;
                            lock (this.tasks)
                            {
                                // When there are no more items to be processed,
                                // note that we're done processing, and get out.
                                if (this.tasks.Count == 0)
                                {
                                    --this.delegatesQueuedOrRunning;
                                    break;
                                }

                                // Get the next item from the queue
                                item = this.tasks.First.Value;
                                this.tasks.RemoveFirst();
                            }

                            // Execute the task we pulled out of the queue
                            TryExecuteTask(item);
                        }
                    } finally
                    {
                        // We're done processing items on the current thread
                        currentThreadIsProcessingItems = false;
                    }
                },
            null);
        }
    }


/// <summary>
    /// Provides a task scheduler that ensures only one task is executing at a time, and that tasks
    /// execute in the order that they were queued.
    /// Source: http://msdn.microsoft.com/en-us/library/ee789351.aspx
    /// Author: Microsoft 2009
    /// </summary>
    public sealed class OrderedTaskScheduler : LimitedConcurrencyLevelTaskScheduler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="OrderedTaskScheduler"/> class. Initializes an instance of the OrderedTaskScheduler class.
        /// </summary>
        public OrderedTaskScheduler() : base(1)
        {
        }
    }



Finally I wrote a test program to prove two things. First, that using the default Task Factory it _might_ complete tasks in a different order than they were queued into the task factory.  And second, that by running with limited concurrency, ie 1 thread, this will guarantee the tasks are completed in the order they were queued.

Here's my test console program:

namespace TaskInGauranteedOrder
{
    using System;
    using System.Collections.Concurrent;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;

    public static class Program
    {
        public static void Main()
        {
            // Test the Schedule to ensure its doing its job correctly
            SchedulerCheck(5);

            // Test Default Factory
            SequenceCheck(null, 500);

            // Test 1 Thread Factory
            SequenceCheck(new LimitedConcurrencyLevelTaskScheduler(1), 1000);
        }

        private static void SchedulerCheck(int maxThreads)
        {
            Console.WriteLine("**** Scheduler Check " + maxThreads + " threads maximum ****");
            var timer = Stopwatch.StartNew();
            var limitedScheduler = new LimitedConcurrencyLevelTaskScheduler(maxThreads);
            var factory = new TaskFactory(limitedScheduler);
            var bag = new ConcurrentDictionary<int, int>();

            var tasks = new Task[1500];
            for (int i = 0; i < 1500; i++)
            {
                tasks[i] = factory.StartNew(() =>
                {
                    int threadid = Thread.CurrentThread.ManagedThreadId;

                    // Console.WriteLine("{0} on thread {1}", i, threadid);
                    if (!bag.ContainsKey(threadid))
                    {
                        bag.TryAdd(threadid, threadid);
                    }
                });
            }
            
            Task.WaitAll(tasks);

            if (bag.Count > maxThreads)
            {
                Console.WriteLine(timer.ElapsedMilliseconds.ToString("#,000") + "ms. Scheduler Check FAILED.");
            } else if (bag.Count < maxThreads)
            {
                Console.WriteLine(timer.ElapsedMilliseconds.ToString("#,000") + "ms. Scheduler Check Warning: Fewer threads used that max specified " + bag.Count + "/" + maxThreads);
            } else
            {
                Console.WriteLine(timer.ElapsedMilliseconds.ToString("#,000") + "ms. Ok.");
            }

            Console.WriteLine();
        }

        private static void SequenceCheck(TaskScheduler scheduler, int iterations)
        {
            var timer = Stopwatch.StartNew();
            TaskFactory factory;
            if (scheduler == null)
            {
                factory = Task.Factory;
                Console.WriteLine("**** Sequence Check ...DEFAULT FACTORY... ****");
            } else
            {
                factory = new TaskFactory(scheduler);
                Console.WriteLine("**** Sequence Check... 1 THREAD FACTORY... ****");
            }

            Console.WriteLine(iterations + " iterations: ");
            bool failed = false;

            // Do it a few times to ensure consistency););
            for (int repeat = 0; repeat < iterations; repeat++)
            {
                var taskExecOrder = new ConcurrentQueue<int>();
                var tasks = new Task[10];
                for (int index = 0; index < 10; index++)
                {
                    int index1 = index;
                    tasks[index] = factory.StartNew(() => taskExecOrder.Enqueue(index1));
                }

                Task.WaitAll(tasks);

                int result = 0, last = -1;
                bool outOfOrder = false;
                while (taskExecOrder.TryDequeue(out result))
                {
                    outOfOrder = outOfOrder | (last != result - 1);
                    last = result;
                }

                if (outOfOrder)
                {
                    failed = true;
                } 

                if (repeat % 3 == 0)
                {
                    Console.Write(".");
                }
            }

            timer.Stop();
            Console.WriteLine();
            if (failed)
            {
                Console.WriteLine(timer.ElapsedMilliseconds.ToString("#,000") + "ms. FAILED! Out of Sequence Order.");
            } else
            {
                Console.WriteLine(timer.ElapsedMilliseconds.ToString("#,000") + "ms. Ok.");
            }

            Console.WriteLine();
        }
    }
}


And the output:
Using the default factory you can see that one or more tasks are completed out of order. Hence the "Failed" text. There are 500 tasks run, so there's a good chance it will complete some out of order if its possible to do so. Lastly using the Limited Concurrency Scheduler with 1 thread, the results are in an expected order.

Tuesday, August 31, 2010

Parallel Extensions

31-August-2010

The new Task Parallel Library included in .NET4 is an incredibly easy way to parallelise processing, that would otherwise have to be done with such devices as SpinLock, Semaphores, Monitors and others.  Unfortunately those previous devices were crazy easy to get wrong, and remember how they worked after 6 months has elapsed.

One of my favourite sessions at TechEd this year showed in some detail how to Parallise various code fragments using the new constructs.  

Parallel Loops

Loops are the easiest place to start (shortly followed thereafter with reconsidering all LINQ statements).

namespace TPLTest1
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    public static class Program
    {
        public static void Main(string[] args)
        {
            Action a1 = () =>
            {
                Thread.Sleep(500);
                Console.WriteLine("Action1");
            };
            Action a2 = () =>
            {
                Thread.Sleep(500);
                Console.WriteLine("Action2");
            };
            Action a3 = () =>
            {
                Thread.Sleep(500);
                Console.WriteLine("Action3");
            };
            Action a4 = () =>
            {
                Thread.Sleep(500);
                Console.WriteLine("Action4");
            };
            Parallel.Invoke(a1, a2, a3, a4);
            Console.WriteLine("Finished");

            Parallel.For(0, 4, index =>
                {
                    Thread.Sleep(500);
                    Console.WriteLine("Enumerator " + index);
                });
            Console.WriteLine("Finished For");
        }
    }
}
The handy thing about these new For constructs are the threads will be synchronised back into the main thread after the loop. Here's the output:
Action1
Action2
Action3
Action4
Finished
Enumerator 2
Enumerator 1
Enumerator 0
Enumerator 3
Finished For
Press any key to continue . . .

PLINQ

To be able to effectively and safely filter a collection and copy results into a new collection you used to have to do something like this:

IEnumerable<RaceCarDriver> drivers = …;
var results = new List<RaceCarDriver>();
int partitionsCount = Environment.ProcessorCount;
int remainingCount = partitionsCount;
var enumerator = drivers.GetEnumerator();
try {
    using (var done = new ManualResetEvent(false)) {
        for(int i = 0; i < partitionsCount; i++) {
            ThreadPool.QueueUserWorkItem(delegate {
                while(true) {
                    RaceCarDriver driver;
                    lock (enumerator) {
                        if (!enumerator.MoveNext()) break;
                        driver = enumerator.Current;
                    }
                    if (driver.Name == queryName &&
                        driver.Wins.Count >= queryWinCount) {
                            lock(results) results.Add(driver);
                    }
                }
                if (Interlocked.Decrement(ref remainingCount) == 0) done.Set();
            });
        }
        done.WaitOne();
        results.Sort((b1, b2) => b1.Age.CompareTo(b2.Age));
    }
}
finally { if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose(); }
Now you do this:

var results = from driver in drivers
              where driver.Name == queryName &&
                    driver.Wins.Count >= queryWinCount              
              orderby driver.Age ascending
              select driver;
Crazy easy.
One of the few options you might need to consider when using PLINQ is the partitioning algorithm used.  Here's a great slide from Ivan Towlson session at TechEd NZ showing the different algorithms in action:
I believe the Chunking algorithm is the default, and usually is an ok choice for most things. Except if you are looking for a certain grouping of data, for example searching a list of people and processing the first one of a series of duplicates, then you should use the Hash algorithm.

Tasks

Best described by two more slides from the same session:
Awesome.

Wednesday, August 4, 2010

Self Hosting in WCF

Self Hosting in WCF can pose some small issues when you would like to host many services in one service.  Here's some template code I have used before to solve this:

Code Download

Why host in a Console?  Usually the intention is to host inside another application or a Windows service, and testing it inside a console a simplier than the real application.  Why not IIS/WAS? If  you need to run long lived background threads hosting in IIS or WAS will have issues.

The main idea is to safely host each service inside a using block and use a controlling thread to signal hosting threads to trigger shut-down.

First I put all metadata for a service into an array of container classes. Then I can loop through and intitialise them, then wait for them all to come online.



           var services = new[]
                               {
                                   new SingleServiceHostContainer(typeof(TestService1), testMode) { Fake = typeof(TestService1Fake) }, 
                                   new SingleServiceHostContainer(typeof(TestService2), testMode) { Fake = typeof(TestService2Fake) }
                               };

            // Have used Threads instead of the task factory to ensure they start
            var hostThreads = new List<Thread>();
            Array.ForEach(
                services, 
                s =>
                    {
                        s.ReadyToExitResetEvent = ReadyToExitResetEvent;
                        var thread = new Thread(s.Run);
                        hostThreads.Add(thread);
                        thread.Start();
                    });

            // Wait for initialisation to complete
            WaitHandle.WaitAll(services.Select(s => s.InitializationComplete).ToArray());
            Array.ForEach(services, s => s.WriteOutputToConsole());

            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Press any key to quit");
            Console.ReadKey();

            ReadyToExitResetEvent.Set();
            hostThreads.ForEach(t => t.Join());


Once they are all signalling they have completed their initialisation, then the main thread can simply wait until the user is ready to close the console and thereby shut down all the services.

There's a little noise in the code download, for things like dependency injection and WCF Data Services (OData services).