Click here to Skip to main content
15,895,746 members
Articles / Programming Languages / C#

High Performance Multi-threaded Work Item / Event Scheduling Engine

Rate me:
Please Sign up or sign in to vote.
4.94/5 (57 votes)
16 Mar 2008CPOL16 min read 138.2K   2.4K   247  
High performance solution for scheduling and executing work items.
using System;
using System.Diagnostics;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrainTechLLC.EmlenMud.Interfaces;
using BrainTechLLC;
using BrainTechLLC.ThreadSafeObjects;

namespace TestLockableSpeedConsole
{
    class Program
    {
        private static int _threadCount;
        private static Queue<object> _testQueue1 = new Queue<object>();
        private static Queue<object> _testQueue2 = new Queue<object>();
        private static Lockable _lock = new Lockable();
        private static object _lockObject = new object();
        private static int _done1;
        private static int _done2;

        static void Main(string[] args)
        {
            const int MaxThreadIterations = 10;
            long time1, time2;
            int count = 0;
            long[] times1 = new long[MaxThreadIterations];
            long[] times2 = new long[MaxThreadIterations];

            for (int n = 20; n <= 80; n += 10)
            {
                _threadCount = n;
                TestLockSpeed(n, out time1, out time2);
                Console.WriteLine("Threads: " + n.ToString() + ", using class Lockable: " + time1.ToString() + " vs. lock(): " + time2.ToString());
                times1[count] = time1;
                times2[count] = time2;
                count++;
            }

            long total1 = 0, total2 = 0;

            for (int n = 0; n < MaxThreadIterations; n++)
            {
                total1 += times1[n];
                total2 += times2[n];
            }

            Console.WriteLine("Total time using class Lockable: " + total1.ToString() + " vs. lock(): " + total2.ToString());
            Console.ReadLine();
        }

        public static void EnqueueAndDequeueWithLockable()
        {
            try
            {
                object o;

                for (int n = 0; n < 1000; n++)
                {

                    for (int i = 0; i < 20; i++)
                    {
                        _lock.AquireLock(); { _testQueue1.Enqueue(i + n); } _lock.ReleaseLock();
                    }

                    int count = 0;

                    lock (_lockObject) { count = _testQueue2.Count; }

                    if (count > 0)
                    {
                        _lock.AquireLock();
                        {
                            if (_testQueue1.Count > 1)
                            {
                                o = _testQueue1.Dequeue();
                                o = _testQueue1.Dequeue();
                            }
                            else if (_testQueue1.Count > 0)
                            {
                                o = _testQueue1.Dequeue();
                            }
                        }
                        _lock.ReleaseLock();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Interlocked.Increment(ref _done1);
        }

        private static void DoLockableEnqueue(int n)
        {
            _lock.AquireLock();
            {
                _testQueue1.Enqueue(n);
            }
            _lock.ReleaseLock();
        }

        private static void DoLockableDequeue()
        {
            object o;

            _lock.AquireLock();
            {
                if (_testQueue1.Count > 0) o = _testQueue1.Dequeue();
            }
            _lock.ReleaseLock();
        }

        private static void DoLockEnqueue(int n)
        {
            lock (_lockObject)
            {
                _testQueue2.Enqueue(n);
            }
        }

        private static void DoLockDequeue()
        {
            object o;

            lock (_lockObject)
            {
                if (_testQueue2.Count > 0) o = _testQueue2.Dequeue();
            }
        }

        public static void EnqueueWithLockable()
        {
            for (int n = 0; n < 1000; n++)
            {
                for (int i = 0; i < 20; i++)
                    DoLockableEnqueue(i + n);

                Thread.Sleep(0);
            }
            Interlocked.Increment(ref _done1);
        }

        public static void DequeueWithLockable()
        {
            for (int n = 0; n < 1000; n++)
            {
                while (_testQueue1.Count > 0)
                    DoLockableDequeue();
            }
            Interlocked.Increment(ref _done1);
        }

        public static void EnqueueWithLock()
        {
            for (int n = 0; n < 1000; n++)
            {
                for (int i = 0; i < 20; i++)
                    DoLockEnqueue(i + n);

                Thread.Sleep(0);
            }
            Interlocked.Increment(ref _done2);
        }

        public static void DequeueWithLock()
        {
            for (int n = 0; n < 1000; n++)
            {
                while (_testQueue2.Count > 0)
                    DoLockDequeue();
            }

            Interlocked.Increment(ref _done2);
        }

        public static void EnqueueAndDequeueWithLock()
        {
            try
            {
                object o;

                for (int n = 0; n < 1000; n++)
                {
                    for (int i = 0; i < 20; i++)
                    {
                        lock (_lockObject) { _testQueue2.Enqueue(i + n); }
                    }

                    int count = 0;

                    lock (_lockObject) { count = _testQueue2.Count; }

                    if (count > 0)
                    {
                        lock (_lockObject)
                        {
                            if (_testQueue2.Count > 1)
                            {
                                o = _testQueue2.Dequeue();
                                o = _testQueue2.Dequeue();
                            }
                            else if (_testQueue2.Count > 0)
                            {
                                o = _testQueue2.Dequeue();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Interlocked.Increment(ref _done2);
        }

        public static void TestLockSpeed(int ThreadCount, out long time1, out long time2)
        {
            _testQueue1.Clear(); _testQueue2.Clear();
            _done1 = 0; _done2 = 0;
            ThreadStart[] tss1 = new ThreadStart[ThreadCount];
            ThreadStart[] tss2 = new ThreadStart[ThreadCount];
            Thread[] threads1 = new Thread[ThreadCount];
            Thread[] threads2 = new Thread[ThreadCount];

            for (int n = 0; n < ThreadCount; n++)
            {
                if (n % 2 == 0)
                {
                    tss1[n] = new ThreadStart(EnqueueWithLockable);
                    threads1[n] = tss1[n].CreateThread();
                    tss2[n] = new ThreadStart(EnqueueWithLock);
                    threads2[n] = tss2[n].CreateThread();
                }
                else
                {
                    tss1[n] = new ThreadStart(DequeueWithLockable);
                    threads1[n] = tss1[n].CreateThread();
                    tss2[n] = new ThreadStart(DequeueWithLock);
                    threads2[n] = tss2[n].CreateThread();
                }
            }

            Stopwatch watch = new Stopwatch();
            watch.Reset();

            watch.Start();
            for (int n = 0; n < ThreadCount; n++)
            {
                threads1[n].Start();
            }

            while (_done1 != ThreadCount)
            {
                Thread.Sleep(10);
            }
            watch.Stop();

            time1 = watch.ElapsedMilliseconds;

            watch.Reset();

            watch.Start();
            for (int n = 0; n < ThreadCount; n++)
            {
                threads2[n].Start();
            }

            while (_done2 != ThreadCount)
            {
                Thread.Sleep(10);
            }
            watch.Stop();

            time2 = watch.ElapsedMilliseconds;
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior) Troppus Software
United States United States
Currently working as a Senior Silverlight Developer with Troppus Software in Superior, CO. I enjoy statistics, programming, new technology, playing the cello, and reading codeproject articles. Smile | :)

Comments and Discussions