programming with esskar

Just another WordPress.com weblog

Posts Tagged ‘WaitHandle

NamedEvents in C# unlimited?

leave a comment »

Due to the fact that .NET offers a great way to use asynchronous eventing, i forgot about the thread-synchronization-events mechanism (CreateEvent, OpenEvent) that i used when programming old-school WINAPI in C/C++. However, I stumbeled about a problem that i could not solve using asynchronous eventing.

.NET offers the EventWaitHandle class which is located in the System.Threading namespace. AutoResetEvent and ManualResetEvent already use it as base class. As i needed named events and to keep thinks simple a wrote two new classes NamedAutoResetEvent and NamedManualResetEvent that wrap around the EventWaitHandle.

using System;
using System.Threading;

namespace Esskar.Threading
{
    public enum NamedEventSpace
    {
        Default, Local, Global,
    }

    public abstract class NamedEvent : EventWaitHandle
    {
        private string m_name;

        public NamedEvent(bool initalState, EventResetMode mode, string name, NamedEventSpace nameSpace)
            : base(initalState, mode, NamedEvent.BuildName(ref name, nameSpace))
        {
            m_name = name;
        }

        public string Name
        {
            get { return m_name; }
        }

        private static string BuildName(ref string name, NamedEventSpace nameSpace)
        {
            if (!string.IsNullOrEmpty(name))
            {
                switch (nameSpace)
                {
                    case NamedEventSpace.Global: name = @"Global\" + name; break;
                    case NamedEventSpace.Local: name = @"Local\" + name; break;
                }
            }
            return name;
        }
    }

    public class NamedAutoResetEvent : NamedEvent
    {
        public NamedAutoResetEvent(bool initialState, string name)
            : this(initialState, name, NamedEventSpace.Default) { }

        public NamedAutoResetEvent(bool initialState, string name, NamedEventSpace nameSpace)
            : base(initialState, EventResetMode.AutoReset, name, nameSpace) { }
    }

    public class NamedManualResetEvent : NamedEvent
    {
        public NamedManualResetEvent(bool initialState, string name)
            : this(initialState, name, NamedEventSpace.Default) { }

        public NamedManualResetEvent(bool initialState, string name, NamedEventSpace nameSpace)
            : base(initialState, EventResetMode.ManualReset, name, nameSpace) { }
    }
}

Since already knew that i could expect a high number (> 30K) of named events to be created, i needed to know whether or not i run into an upper limit. So i wrote a little test program

using System;
using Esskar.Threading;

namespace Esskar.Testing.NamedEvents
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";            
            const int defCount = 10 * 1000;

            int count = defCount;
            if (args.Length > 0) count = int.Parse(args[0]);
            if (count <= 0) count = defCount;

            Console.WriteLine(string.Format("About to create {0} named events.", count));
            NamedEvent[] tmp = new NamedEvent[count];
            for(int i = 0; i < count; i++)
            {
                tmp[i] = new NamedAutoResetEvent(false, name + i);
                if (tmp[i].SafeWaitHandle.IsInvalid)
                    throw new Exception(string.Format("Unable to create event #{0}", i));
                if ((i % 100) == 0) Console.Write('.');
            }
            Console.ReadLine();
        }
    }
}

that would create me number of named threads based on a commandline argument. As you try it, you will notice the speed of the progress-points will decrease as the number of created events increases. I was still able to create 100K events without any problem.

Written by esskar

February 19, 2009 at 2:37 pm

Follow

Get every new post delivered to your Inbox.