Thursday, February 21, 2008

.NET Threading - AutoResetEvent And ManualResetEvent

In .NET EventWait handles are used for signaling for threads' communication. Signaling is when one thread waits until it receives notification from another. AutoResetEvent and ManualResetEvent are two EventWait handles available in .NET 2.0. AutoRsetEvent allows a thread to unblock once when it receives a signal from another and then it automatically resets. ManualResetEvent won't do reset by itself unless you do it manually. Following code sample demos such concept:
using System;
using System.Threading;

class Test
{
static void Main()
{
AutoResetEvent autoReset = new AutoResetEvent(false);
ManualResetEvent manualReset = new ManualResetEvent(false);
WaitHandle[] events = new WaitHandle[2] { autoReset, manualReset };

//Start 3 threads with AutoResetEvent
for (int i = 0; i < 3; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Run), autoReset);
}
Thread.Sleep(1000);
autoReset.Set();
Thread.Sleep(1000);
Console.WriteLine();

//Start 3 threads with ManualResetEvent
for (int i = 0; i < 3; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Run), manualReset);
}
Thread.Sleep(1000);
manualReset.Set();
Thread.Sleep(1000);

Console.WriteLine("\nMain thread completed...");
Console.ReadLine();
}

static void Run(object obj)
{
EventWaitHandle hander = obj as EventWaitHandle;
Console.WriteLine("Thread {0} is started and blocked...", Thread.CurrentThread.ManagedThreadId);
hander.WaitOne();
Console.WriteLine("Thread {0} is unblocked...", Thread.CurrentThread.ManagedThreadId);
}
}
Result:

Saturday, February 02, 2008

.NET 2.0 Configuration AppSettings In Custom Section

App.config or Web.config:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="MyCustomSection" type="CustomSettingManager, ConsoleApplication1"/>
</configSections>
<MyCustomSection>
<appSettings>
<add key="Key1" value="Value1"/>
<add key="Key2" value="Value2"/>
</appSettings>
</MyCustomSection>
</configuration>
Code behind:
using System;
using System.Configuration;

class Test
{
static void Main()
{
Console.WriteLine("Key:{0} Value:{1}", "key1", CustomSettingManager.GetCustomSetting("key1"));
Console.Read();
}
}

public class CustomSettingElement : ConfigurationElement
{
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get { return this["key"] as string; }
}
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return this["value"] as string; }
}
}

public class CustomSettingCollection : ConfigurationElementCollection
{
public CustomSettingElement this[int index]
{
get
{
return base.BaseGet(index) as CustomSettingElement;
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}

protected override ConfigurationElement CreateNewElement()
{
return new CustomSettingElement();
}

protected override object GetElementKey(ConfigurationElement element)
{
return ((CustomSettingElement)element).Key;
}
}

public class CustomSettingManager : ConfigurationSection
{
private const string sectionName = "MyCustomSection";
private const string collectionName = "appSettings";
private static CustomSettingManager configSection =
ConfigurationManager.GetSection(sectionName) as CustomSettingManager;

public static string GetCustomSetting(string key)
{
string value = string.Empty;
if (configSection != null && configSection[collectionName] != null)
{
CustomSettingCollection appSettings =
configSection[collectionName] as CustomSettingCollection;
foreach (CustomSettingElement item in appSettings)
{
if (string.Compare(item.Key, key, true) == 0)
{
value = item.Value;
}
}
}
return value;
}

[ConfigurationProperty(collectionName)]
public CustomSettingCollection AppSettings
{
get
{
return this[collectionName] as CustomSettingCollection;
}
}
}