.NET WaitHandles, Events, IPC, Subscribers and All That Sort of Thing

AID: 4235
  • Status: Published

1680 points

  • Byegl1044
  • TypeResource
  • Posted on2010-12-19 at 22:38:55
This article will discuss some interesting things that can be done using the WaitHandle class if only the full power they offer is looked at closely. In almost every situation the WaitHandle class is used to synchronize access between threads or wait on operations to be completed where execution can then take off from that point in time. However lets take another look at the possibilities this class can offer thinking outside the box.

You may be familiar with using this class in a single application in many cases to synchronize threads, BUT what if we took this class a step further and used it in a strange way that is often overlooked? Just consider for a moment that you are building your application and you would like to share special events to other applications well refer to them as subscribers. Similar to (Windows Messaging) without the window handles and message queues?

Have a look at the table below to become familiar with some keywords.

Client
The main application or owner. Regardless of what this application does it can offer the ability to share events to others if they wish to subscribe as a (subscriber).

Subscribers
Subscribes to the owner(client) to receive events when the client signals.

"" title="Building the client and discussing important factors that need to be considered."]



In order to begin building your client we'll need a WaitHandle object.
EventWaitHandle Class
http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

Know your event mode


The idea is to create what is known as a "named event object". The subscribers can use the name to subscribe to your events in there own applications. Now before going further it's important to understand the difference between how a particular event mode works.

AutoReset
When signaled, the EventWaitHandle resets automatically after releasing a single thread. If no threads are waiting, the EventWaitHandle remains signaled until a thread blocks, and resets after releasing the thread.
ManualReset
When signaled, the EventWaitHandle releases all waiting threads and remains signaled until it is manually reset.

It's important to choose the right type of event mode for your client. If you decide to use an AutoResetEvent then only one subscriber will be notified for each call made to .Set() which means if you have multiple subscribers and the client calls .Set() once only one subscriber is notified. This would require your client to know how many subscribers it is working with so it can call the .Set() method as many times as needed for the number of subscribers.  In this particular case we want the ability to notify everyone without knowing how many subscribed.

The ManualReset event is the clear winner since our client can call .Set() once to notify all subscribers then immediately call .Reset() to put them back into there respective waiting cycle.

No, you as a subscriber can't play, tinker, or change my events. They're mine!



It's important that when setting up your clients event object you only allow subscribers the ability to Wait or Synchronize with your event. If you don't take the steps to ensure the proper access rights on your event many bad things can happen. Ever hear the phrase "one bad apple spoils the whole bunch?" Well, one bad subscriber can ultimately take control and tinker with your events by setting them to non-signaled or taking ownership. This is important especially if you decide to hand out your event object's name. Even better would be to randomly generate an event name and add it to the atom table and have them pull the name from the table. This ensures your client would have been the first one to create the named event reducing the likelihood of a bad apple opening the named event for the sole purpose of causing havoc to running subscribers. In reference to some applications opening the named event before the client, it's very unlikely this would ever happen but it's something that should be mentioned. However security on your event is absolutely necessary.

The client can accomplish security using the following classes.

EventWaitHandleSecurity
EventWaitHandleAccessRule

Put the client into practice



Hopefully the above information made you a little more familiar with how the clients named event should be played out. Now we can put that information into practice. The Client in the following example is simply a Windows Form Application and a button with a touchy trigger finger.

Create new Windows Form Application
Add one button to the form
Set the button caption:Trigger



In the code above we created a named event object called EEArticle and set strict rules for how subscribers can access our object. In this case any and all subscribers have the ability to synchronize or (wait) until the client signals the event. If a subscriber attempts to open the event with any other type of access they should be ashamed of themselves and be denied dinner for the night.

"" title="Building the subscriber. Discuss how a subscriber can subscribe to the client."]



Now that you have built your client with good security measures, it's time to give subscribers the ability to subscribe to your client. In order to do that you can share your clients event name. In our client example that is: EEArticle

There is not much that changes for subscribers. Like the client, the subscriber also uses the EventWaitHandle Class but in a slightly different manner.  Since the client is known as the owner, the subscriber needs to open the existing named event object.

The subscriber uses the shared EventWaitHandle.OpenExisting method and specifies the name of the event the client created. Again EEArticle.

In order for the subscriber to wait for signals from the client, they can use one ThreadPool and register the named event with the ThreadPool. The ThreadPool will wait until the client signals the event object. When this occurs it sets our open event object into a signaled state, the ThreadPool fires off into a specified callback and we as a subscriber are notified whenever the client decides to get a touchy trigger finger. The way that we set up the ThreadPool initially will automatically re-wait for additional events until we choose to UnSubscribe.

Put the subscriber into practice



The subscriber in this example is simply a Windows Form Application with nothing added to the form but the subscriber code itself.



Real World Example



Scratching the surface



Hopefully you found this interesting. Just how useful this type of mechanism becomes depends on how far you are willing to take this example and improve upon it.  On the surface this particular example in the article is not extremely useful but you could use Named Shared Memory and use this approach to synchronize when your client writes information into the shared view, allowing subscribers to pick up the information (a structure) and use it to their heart's content. This is just one approach that could be used to share information between processes or simply informing child applications or others that a particular (action) has occurred in your application.

To create named shared memory and extend this example into passing something useful to your subscribers you may want to consider using the new MemoryMappedFile Class which has only been introduced with .NET 4.0 framework.

MemoryMappedFile Class
http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx

The Client uses:
MemoryMappedFile.CreateNew
http://msdn.microsoft.com/en-us/library/dd267552.aspx

The Subscriber uses:
MemoryMappedFile.OpenExisting
http://msdn.microsoft.com/en-us/library/dd267590.aspx

In this respect the example starts to become more useful as when the client writes information into the shared memory it can notify subscribers that new information is available. The subscriber can pick up the new information and work with it any way it chooses.

Final thoughts



The goal of this article is to show how the WaitHandle class can be used differently instead of only thinking about them as something internal to your single application. There are better alternative ways to (IPC) this is just another way thinking outside the box and taking a single class and making something interesting. Many coming to the .NET world might not know how events can be used and there purpose, those that are familiar can look at this article and see something in .NET that they probably have never seen done before after all programming is about having fun and coming up with funky ideas.

:)
Asked On
2010-12-19 at 22:38:55ID4235
Tags

WaitHandle

,

Events

,

IPC

,

Named Event

,

EventWaitHandle

,

ThreadPool

,

.NET IPC

,

Name Shared Memory

Topic

Microsoft Visual Basic.Net

Views
1111

Comments

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top Visual Basic.NET Experts

  1. CodeCruiser

    1,541,075

    Genius

    8,400 points yesterday

    Profile
    Rank: Genius
  2. kaufmed

    303,871

    Wizard

    500 points yesterday

    Profile
    Rank: Genius
  3. Idle_Mind

    230,817

    Guru

    2,010 points yesterday

    Profile
    Rank: Savant
  4. nepaluz

    192,076

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  5. PaulHews

    161,438

    Guru

    520 points yesterday

    Profile
    Rank: Genius
  6. BuggyCoder

    150,598

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  7. JamesBurger

    123,179

    Master

    0 points yesterday

    Profile
    Rank: Sage
  8. emoreau

    112,211

    Master

    0 points yesterday

    Profile
    Rank: Genius
  9. Masteraco

    102,128

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  10. TheLearnedOne

    80,982

    Master

    0 points yesterday

    Profile
    Rank: Savant
  11. Dhaest

    63,803

    Master

    2,000 points yesterday

    Profile
    Rank: Genius
  12. MlandaT

    53,803

    Master

    2,100 points yesterday

    Profile
    Rank: Genius
  13. wdosanjos

    53,796

    Master

    0 points yesterday

    Profile
    Rank: Genius
  14. mlmcc

    53,048

    Master

    0 points yesterday

    Profile
    Rank: Savant
  15. RolandDeschain

    41,679

    10 points yesterday

    Profile
    Rank: Sage
  16. srosebabu

    31,025

    2,000 points yesterday

    Profile
    Rank: Guru
  17. mas_oz2003

    28,400

    0 points yesterday

    Profile
    Rank: Genius
  18. sedgwick

    27,350

    0 points yesterday

    Profile
    Rank: Genius
  19. jacko72

    26,596

    0 points yesterday

    Profile
    Rank: Genius
  20. tommyBoy

    25,850

    0 points yesterday

    Profile
    Rank: Genius
  21. dlmille

    22,160

    0 points yesterday

    Profile
    Rank: Genius
  22. imnorie

    21,664

    1,600 points yesterday

    Profile
    Rank: Genius
  23. Cluskitt

    21,418

    0 points yesterday

    Profile
    Rank: Wizard
  24. robert_schutt

    20,440

    0 points yesterday

    Profile
    Rank: Guru
  25. navneethegde

    20,332

    0 points yesterday

    Profile
    Rank: Wizard

Hall Of Fame