Recipe18.13.Get the Naming Rights for Your Events


Recipe 18.13. Get the Naming Rights for Your Events

Problem

You want to have code running in worker threads, or in other processes or appdomains, to be able to wait on an event.

Solution

Use the EventWaitHandle class, new to the 2.0 Framework. With it, you can create a named event that will allow any code running on the local machine to find and wait on the event. AutoResetEvent and ManualResetEvent are excellent for signaling events in threaded code and even between appdomains if you are willing to go through the hassle of passing the event reference around. Why bother? Both of them derive from EventWaitHandle, but neither exposes the naming facility. EventWaitHandle can not only take the name of the event, but also can take an EventresetMode parameter to indicate if it should act like a ManualResetEvent (EventResetMode.ManualReset) or an AutoResetEvent (EventResetMode.AutoReset). Named events have been available to Windows developers for a long time, and the EventWaitHandle class can serve as a named version of either an AutoResetEvent or a ManualResetEvent.

To set up a named EventWaitHandle that operates as a ManualResetEvent, do this:

 // Make a named manual reset event. EventWaitHandle ewhSuperBowl =     new EventWaitHandle(false, // Not initially signaled                         EventResetMode.ManualReset,                         @"Champs"); // Spin up three threads to listen for the event. for (int i = 0; i < 3; i++) {     Thread t = new Thread(ManualFan);     // The fans wait anxiously…     t.Name = "Fan " + i;     t.Start(); } // Play the game. Thread.Sleep(10000); // Notify people. Console.WriteLine("Patriots win the SuperBowl!"); // Signal all fans. ewhSuperBowl.Set(); // Close the event. ewhSuperBowl.Close(); 

The ManualFan method is listed here:

 public static void ManualFan() {     // Open the event by name.     EventWaitHandle ewhSuperBowl =         new EventWaitHandle(false,                             EventResetMode.ManualReset,                             @"Champs");     // Wait for the signal.     ewhSuperBowl.WaitOne();     // Shout out.     Console.WriteLine("\"They're great!\" says {0}",Thread.CurrentThread.Name);     // Close the event.     ewhSuperBowl.Close(); } 

The output from the manual event code will resemble the listing here (the ManualFan tHReads might be in a different order):

 Patriots win the SuperBowl! "They're great!" says Fan 2 "They're great!" says Fan 1 "They're great!" says Fan 0 

To set up a named EventWaitHandle to operate as an AutoResetEvent, do this:

 // Make a named auto reset event. EventWaitHandle ewhSuperBowl =     new EventWaitHandle(false, // Not initially signalled                         EventResetMode.AutoReset,                         @"Champs"); // Spin up three threads to listen for the event. for (int i = 0; i < 3; i++) {     Thread t = new Thread(AutoFan, i);     // The fans wait anxiously…     t.Name = "Fan " + i;     t.Start(); } // Play the game. Thread.Sleep(10000); // Notify people. Console.WriteLine("Patriots win the SuperBowl!"); // Signal one fan at a time. for (int i = 0; i < 3; i++) {     Console.WriteLine("Notify fans");     ewhSuperBowl.Set(); } // Close the event. ewhSuperBowl.Close(); 

The AutoFan method is listed here:

 public static void AutoFan() {     // Open the event by name.     EventWaitHandle ewhSuperBowl =         new EventWaitHandle(false,                             EventResetMode.AutoReset,                             @"Champs");     // Wait for the signal.     ewhSuperBowl.WaitOne();     // Shout out.     Console.WriteLine("\"Yahoo!\" says {0}", Thread.CurrentThread.Name);     // Close the event.     ewhSuperBowl.Close(); } 

The output from the automatic event code will resemble the listing here (the AutoFan threads might be in a different order):

 Patriots win the SuperBowl! Notify fans "Yahoo!" says Fan 0 Notify fans "Yahoo!" says Fan 2 Notify fans "Yahoo!" says Fan 1 

Discussion

EventWaitHandle is defined as deriving from WaitHandle, which in turn derives from MarshalByRefObject. EventWaitHandle implements the IDisposable interface.

 public class EventWaitHandle : WaitHandle public abstract class WaitHandle : MarshalByRefObject, IDisposable 

WaitHandle derives from MarshalByRefObject so you can use it across appdomains, and it implements IDisposable to make sure the event handle gets released properly.

The EventWaitHandle class can also open an existing named event by calling the OpenExisting method and get the event's access-control security from GetAccessControl.

When naming events, one consideration is how it will react in the presence of terminal sessions. Terminal sessions are the underlying technology behind Fast User switching and Remote Desktop, as well as Terminal Services. The consideration is due to how kernel objects (such as events) are created with respect to the terminal sessions. If a kernel object is created with a name and no prefix, it belongs to the Global namespace for named objects and is visible across terminal sessions. By default, EventWaitHandle creates the event in the Global namespace. A kernel object can also be created in the Local namespace for a given terminal session, in which case the named object belongs to the specific terminal session namespace. If you pass the Local namespace prefix (Local\[EventName]), then the event will be created in the local session for events that should be visible from only one terminal session.

     // Open the event by local name.     EventWaitHandle ewhSuperBowl =         new EventWaitHandle(false,                             EventResetMode.ManualReset,                             @"Local\Champs"); 

Named events can be quite useful not only when communicating between processes, appdomains, or threads, but also when debugging code that uses events, as the name will help you identify which event you are looking at if you have a number of them.

See Also

See the "EventWaitHandle," "AutoResetEvent," "ManualResetEvent," and "Kernel Object Namespaces (Platform SDK Help)" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net