Archive

Posts Tagged ‘Synchronization’

Basic Thread Coordination Part 1

November 23, 2010 Leave a comment

When threads are created they run interdependently from the thread that created them. This is exactly what we want. However we often need to wait for multiple threads doing work to finish before continuing. This is done with the Join() method on the thread which blocks the main thread while waiting till the thread completes.

using System;
using System.Threading;

namespace ThreadsAreForScheduling
{

    public static class ThreadExtensions
    {
        public static void JoinAll(params Thread[] threads)
        {
            Array.ForEach(threads, thread => thread.Join());
        }

        public static void JoinAll(TimeSpan timeout, params Thread[] threads)
        {
            Array.ForEach(threads, thread => thread.Join(timeout));
        }
    }

    public class Program
    {
        public static void Main()
        {

            Program p = new Program();
            p.CreatingThreadsToToRunCalculations();

            Console.WriteLine("Press any key to quit...");
            Console.ReadKey();
        }

        public void CreatingThreadsToToRunCalculations()
        {
            Thread t1 = new Thread(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("10^1: {0}", CalculatePower(10, 1));
            });
            Thread t2 = new Thread(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("10^2: {0}", CalculatePower(10, 2));
            });
            Thread t3 = new Thread(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("10^3: {0}", CalculatePower(10, 3));
            });
            Thread t4 = new Thread(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("10^4: {0}", CalculatePower(10, 4));
            });

            t1.Start();
            t2.Start();
            t3.Start();
            t4.Start();

            ThreadExtensions.JoinAll(t1, t2, t3, t4);
            
            // The above is equivalent to
            // t1.Join();
            // t2.Join();
            // t3.Join();
            // t4.Join();

        }

        private int CalculatePower(int a, int power)
        {
            if (power == 1) return 10;
            int value = 10;

            for (var i = 1; i < power; i++)
            {
                value *= 10;
            }
            return value;
        }
    }
}

Blair

Heavy handed synchronisation with ContextBoundObjects and the Synchronization Attribute

November 4, 2010 Leave a comment

Most people are aware of the lock keyword or Monitor Class in .NET, but most are not awared of the Synchronization attribute and the ContextBoundObject base class.
If you make you class inherit from ContextBoundObject .NET will automatically synchronize all method calls made on that class so you do not need to wrap access to the object inside a lock it does it for you automagically.Well it does this by actually creating a proxy around your object. Method calls are actually intercepted which makes it lok like its magic:)

The Syncronization attribute is a form of declarative locking.

There is a cost however it is about 50 times slower than using a lock.

Here the code.

using System;
using System.Runtime.Remoting.Contexts;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Concurrent;
using System.Runtime.Remoting;

namespace TPLTasks
{

    [Synchronization]
    public class Counter : ContextBoundObject
    {
        public int Value { get; set; }

        public void Increment()
        {
            Value++;
        }
    }

    class Program
    {
        static void Main()
        {

            Counter c = new Counter();
            Task[] tasks = new Task[10];

            for (int i = 0; i <= tasks.Length - 1; i++)
            {
                tasks[i] = Task.Factory.StartNew(
                    () =>
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            c.Increment();
                        }
                    }
                    );
            }

            Task.WaitAll(tasks);
            Console.WriteLine(c.Value);

            Console.WriteLine("Press any key to quit..");
            Console.ReadKey();
        }


    }
}