Posts Tagged ‘WaitHandle’
NamedEvents in C# unlimited?
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.