Click here to Skip to main content
Click here to Skip to main content

EventBroker: a notification component for synchronous and asynchronous, loosly coupled event handling

By , 26 Oct 2008
 

EventBroker.png

Preface

This article is a response to the article Weak Events in C# by Daniel Grunwald.

Introduction

EventBroker is a component that you can use to fire and receive notifications in your system.

Features

  • Loose Coupling:
  • The subscriber does not have to know the publisher. Both of them only need to know the EventTopic URI (a string uniquely identifying the EventTopic in the system). This facilitates building loosely coupled systems.

  • Thread Synchronization:
  • The subscriber defines on which thread the subscription handler is executed:

    • Same thread as publisher (synchronous)
    • Background thread (asynchronous)
    • User interface thread (synchronous or asynchronous)

    Publishers can restrict subscriptions to events to be synchronous or asynchronous.

  • Multiple Publishers/Subscribers:
  • Several publishers/subscribers can fire/handle the same EventTopic.

  • Weak References:
  • Publishers and subscribers are referenced by weak references which will not prevent them from being garbage collected – like in the normal event registration model.

  • Scope:
    • Scope per EventBroker:
    • Only publishers and subscribers that are registered on the same EventBroker are wired together when events are fired. Normally, you'll use a single EventBroker in your system that handles all event notifications. However, in special cases, it is useful to define a new EventBroker for a sub system. This gives you the possibility to define a scope for your event notification.

    • Scope with hierarchical naming:
    • Publishers and subscribers can be named in a hierarchical way, and events can be global, to parents only, or to children only. Both publishers and subscribers can define the scope they publish to/receive from.

Background

This EventBroker is based upon the EventBroker from the Composite (UI) Application Block from Microsoft. See the section Comparison to CAB EventBroker below, for differences.

Using the code

Sample publisher

Publish an event topic:

public class Publisher
{
    [EventPublication("topic://EventBrokerSample/SimpleEvent")]
    public event EventHandler SimpleEvent;
    
    ///<summary>Fires the SimpleEvent</summary>
    public void CallSimpleEvent()
    {
        SimpleEvent(this, EventArgs.Empty);
    }
}

Register the publisher with your event broker (you have to hold an instance of the event broker somewhere in your code). The sample assumes there is a service that holds the event broker instance for us:

EventBroker eb = Service.EventBroker;
Publisher p = new Publisher();
eb.Register(p);

On registration of the publisher, the event broker inspects the publisher for published events (events with the EventPublication attribute).

Sample subscriber

Subscribe to an event topic:

public class Subscriber
{
    [EventSubscription(
        "topic://EventBrokerSample/SimpleEvent", 
        typeof(Handlers.Publisher))]
    public void SimpleEvent(object sender, EventArgs e)
    {
        // do something useful or at least funny
    }
}

Register the subscriber with the event broker:

EventBroker eb = Service.EventBroker; 
Subscriber s = new Subscriber();
eb.Register(s); 

The event broker will inspect the subscriber, on registration, for subscription to event topics (methods with the EventSubscription attribute).

If a publisher fires an event topic for that subscribers are registered, then the event broker will relay them to the subscribers by calling the subscription handler methods with the sender and Eventargs the publisher used to fire its event.

Publication options

Simple

[EventPublication("Simple")]
public event EventHandler SimpleEvent;

With custom Eventargs

Note: CustomEventArgs has simply to be derived from EventArgs.

[EventPublication("CustomEventArgs")]
public event EventHandler<CustomEventArguments> CustomEventArgs;

Publish multiple event topics with one single event

[EventPublication("Event1")]
[EventPublication("Event2")]
[EventPublication("Event3")]
public event EventHandler MultiplePublicationTopics;

Allow only synchronous subscription handlers

See the sections Comparison to CAB EventBroker/Subscription handler restrictions for more details.

[EventPublication("test", HandlerRestriction.Synchronous)]
public event EventHandler AnEvent; 

Allow only asynchronous subscription handlers

See the section Comparison to CAB EventBroker/Subscription handler restrictions for more details.

[EventPublication("test", HandlerRestriction.Asynchronous)]
public event EventHandler AnEvent;

Subscription options

Simple

[EventSubscription("Simple", typeof(Handlers.Publisher)]
public void SimpleEvent(object sender, EventArgs e) {} 

Custom Eventargs

[EventSubscription("CustomEventArgs"), typeof(Handlers.Publisher))]
public void CustomEventArgs(object sender, CustomEventArgs e) {} 

Subscribe multiple event topics

[EventSubscription("Event1", typeof(Handlers.Publisher))]
[EventSubscription("Event2", typeof(Handlers.Publisher))]
[EventSubscription("Event3", typeof(Handlers.Publisher))]
public void MultipleSubscriptionTopics(object sender, EventArgs e) {} 

Execute handler on background thread (asynchronous)

The event broker creates a worker thread to execute the handler method on. The publisher can immediately continue processing.

[EventSubscription("Background", typeof(Handlers.Background))]
public void BackgroundThread(object sender, EventArgs e) {} 

Execute handler on UI thread

Use this option if calling from a background worker thread to a user interface component that updates the user interface - no need for Control.Invoke(...) anymore.

[EventSubscription("UI", typeof(Handlers.UserInterface))]
public void UI(object sender, EventArgs e) {}

Note that if you use the UserInterface handler, then you have to make sure that you register the subscriber on the user interface thread. Otherwise, the EventBroker won't be able to switch to the user interface thread, and will throw an exception.

Execute handler on UI thread asynchronously

The same as above, but the publisher is not blocked until the subscriber has processed the event.

[EventSubscription("UIAsync", typeof(Handlers.UserInterfaceAsync))]
public void UI(object sender, EventArgs e) {}  

Fire event topics directly on EventBroker

Event topics can be fired directly on the EventBroker without the need of registering a publisher. This comes in handy whenever you need to fire an event topic from an object that lives only very shortly.

A good example for such a scenario is a scheduled job execution. At the scheduled time, an instance of a job class is instantiated and executed. It would be cumbersome to register this instance, fire the event, and unregister it again - it's far easier to fire the event directly on the EventBroker:

eventBroker.Fire("topic", sender, eventArgs);

Scope

Sometimes it is necessary to limit the scope an event is published to. This can be achieved in two different ways:

Multiple instances of event brokers

Subscribers can only listen to events of publishers that are registered on the same event broker. Therefore, an event broker automatically builds a scope.

This is the easiest solution to have several event handling scopes in your application, and should always be preferred. However, sometimes, you need more control over scopes within the objects on one single event broker. This scenario is described in the following section.

Hierarchical naming

Publishers and subscribers can be named by implementing the INamedItem interface. This interface provides a single property:

string EventBrokerItemName { get; }

This allows identifying an object within the event broker whereas the publication and subscription attributes are always bound to the class.

The naming is hierarchical by using the same scheme as namespaces:

  • Test is a parent of Test.MyPublisher1
  • Test.MyName1 is a sibling of Test.MyName2
  • Test.MyName1.Subname is a child of Test.MyName1
  • Test.MyName1 is a twin of Test.MyName1 (two objects with the same name are twins)

Now, a publisher can define the scope it wants to publish the event to, by defining a scope in the publication attribute:

[EventPublication("Topic")]
public event EventHandler PublishedGlobally;

[EventPublication("Topic", typeof(ScopeMatchers.PublishToParents)]
public event EventHandler PublishedToParentsAndTwinsOnly;

[EventPublication("Topic", typeof(ScopeMatchers.PublishToChildren)]
public event EventHandler PublishedToChildrenAndTwinsOnly;

The first event is a global event that all subscribers can receive. The second event is only passed to subscribers that are parents or twins of the publisher. The third event is only passed to subscribers that are children or twins of the publisher.

A subscriber can define the scope it wants to receive events from accordingly:

[EventSubscription("Topic", typeof(Handlers.Publisher)]
public void GlobalHandler(object sender, EventArgs e)

[EventSubscription(
    "Topic", 
    typeof(Handlers.Publisher), 
    typeof(ScopeMatchers.SubscribeToParents)]
public void ParentHandler(object sender, EventArgs e)

[EventSubscription(
    "Topic", 
    typeof(Handlers.Publisher), 
    typeof(ScopeMatchers.SubscribeToChildren)]
public void ChildrenHandler(object sender, EventArgs e)

The first subscription is a global subscription that will handle all the events passed to it. The second subscription will only be called when a parent of the subscriber is firing the event. The third subscription will only be called when a child of the subscriber is firing the event.

Twins (different objects with the same name) are handled specially. A twin is always a parent and child of its twin, and will therefore will always receive all the events from its twin.

Comparison to CAB EventBroker

As stated in the Background section, my EventBroker is based on the EventBroker from CAB (Composite UI Application Block) from the Practices and Patterns group of Microsoft.

This section describes the differences.

Standalone

The bbv.Common EventBroker can be used standalone. You can use it anywhere in your projects you need notification, without any framework constraints as CAB would require.

Developer guidance

I tried to implement the EventBroker in a way that errors get visible as soon as possible. I will give you some examples of what that means:

  • If the type of EventHandler the published event provides does not match the signature the subscription handler provides, then an exception is thrown at registration time, instead of when the event is fired.
  • If you use the UserInterface or UserInterfaceAsync subscription handlers, then an exception is thrown at registration time if no WindowsFormsSynchronizationContext is present, that means the current thread is not the user interface thread. This would lead to cross threading exceptions when handling events.

Subscription handler restrictions

Note: this feature is only available in the version hosted on Sourceforge.net (see the section Download) and not in the attached solution (it's too new ;-) ).

We had the problem that some publisher has to be sure that all subscribers handle its event synchronously. For example, if you publish a cancel event, providing a way for all subscribers to cancel the current operation. Only if no subscriber sets the Cancel property on the CancelEventArgs to true can the publisher proceed with its operation. Therefore, the publisher has to restrict all subscriptions on this event to be synchronous:

[EventPublication("test", HandlerRestriction.Synchronous)]
public event EventHandler AnEvent;

If a subscriber registers an asynchronous handler for this event, then an exception is thrown. Note that the exception is thrown at registration time, and not when the event is fired. This simplifies writing consistent code a lot.

Furthermore, a publisher can restrict subscription handlers to be asynchronous because the publisher does not want to be blocked:

[EventPublication("test", HandlerRestriction.Asynchronous)]
public event EventHandler AnEvent;

Logging

The EventBroker of bbv.Common is quite chatty in terms of log messages. This enables you to see when a publisher fires an event, how they are routed to subscribers, how they are handled, and which exceptions occurred.

Note: bbv.Common uses log4net to log messages. That means, you can configure the level of messages logged for each component.

Extensibility

ThreadOption --> Handler

I replaced the enum ThreadOption with extensible handlers to define the way the event is handled (synchronously, asynchronously).

Scope --> Scope Matcher

You can implement your own scope matchers to provide an event hierarchy that suits your needs instead of specifying a scope with an enum.

Internals

We'll have a look at the internals on a next update of this article. Until then, please refer to the source code available in the download.

Download

The download at the top of this article contains three Visual Studio 2008 projects:

  1. bbv.Common.EventBroker: the event broker component.
  2. bbv.Common.EventBroker.Test: the unit tests (NUnit).
  3. bbv.Common.EventBroker.Sample: a small sample application (basic usage of event broker).

The bbv.Common.EventBroker is part of a larger library containing some other cool components, which can be found here.

This download is just a stripped down version. To try it out, open the solution, set the start up project to bbv.Common.EventBroker.Sample, and hit F5.

Note that the version attached to this article is not the latest available. Be sure to check the Sourceforge page for the latest release.

License

Note that the bbv.Common.EventBroker is licensed under Apache License 2.0, but because the EventBroker contains parts of the CAB from Microsoft, additional license restrictions have to be applied, see file headers in the source code for details.

History

  • 2008-10-11 - Initial version.
  • 2008-10-19 - Added comparison to CAB EventBroker, added link to Sourceforge.net.
  • 2008-10-26 - Added the section Fire event topics directly on EventBroker.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Urs Enzler
Architect bbv Software Services AG
Switzerland Switzerland
Member
Urs Enzler is working for bbv Software Services in Switzerland as a Software Architect.
 
Blogger at planetgeek.ch

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralRe: asp.netmemberjinyen17 Feb '10 - 0:25 
hi Urs
 
I am trying to find a way to unregister/register publisher and subscriber per request. the way its been done we unregister ALL publisher/subscribers whenever a page is been called. that works fine when there is only a single user. things don't work as planned when we have several concurrent users logged on Smile | :) . How would you unregisters "specific" publishers/subcribers" per page reqguest?
 
cheers
joe
GeneralRe: asp.netmemberUrs Enzler17 Feb '10 - 1:56 
I would make sure that the event broker is stored in the session of the user. Then there is no "cross-talk" between different users. Global subscribers and publishers have to be registered on every "user" event broker, of course.
 
Cheers,
Urs
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: asp.netmemberjinyen18 Feb '10 - 4:12 
having an event broker per session, would it impact performance? in the app i am building expected number of concurrent users 100+
GeneralRe: asp.netmemberUrs Enzler20 Feb '10 - 5:12 
See here for event performance: http://www.planetgeek.ch/2009/07/12/event-broker-performance/[^]
 
Creating an event broker is very cheap. Registration and deregistration are the operations that can hurt performance. However, I don't have real world experience on the number of registrations/deregistrations you describe you'll have in your application.
 
There is a potential for performance optimization if necessary (the problem: reflection is used to get events and handler methods. This information could however be cached per type).
 
Hope that helps
Urs
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: asp.netmemberCapt Nasty2 Apr '12 - 10:03 
You are correct there is a problem but you missed it. This is not "Loosely Coupled Event Handling" as you have advertised.
 
The point of a loosely coupled event architecture is to provide an abstractions so that Subscriber components do not have any knowledge of potential publishers (Particularly their type!). They also allow a system to function when publishers and subscribers may or may not be present based on security/configuration/etc (Think portal...). Here's a tip: if a type has knowledge of another type at compile time, you are tightly coupled. Coupling is a measure of the direct knowledge and dependency that two types have at COMPILE time. Given that:
 
1) You have to provide a typename of a class
2) The typename is embedded into the assenbly at COMPILE TIME
3) The typename cannot be changed without recompiling your assembly
 
You should change the title to the article it is inaccurate and misleading.
GeneralRe: asp.netmemberUrs Enzler2 Apr '12 - 20:43 
Hi Capt Nasty
 
Thanks for your feedback. There seems to be a misunderstanding.
 
The event broker works exactly as you describe it should. Maybe you got confused by the handler type that specifies how the event is handled.
 
[EventSubscription("topic", typeof(Handler))]
 
There exist handlers for handling the event on the same thread as the event is fired (Publisher), on a background thread (Background) or in the user interface (UserInterface/UserInterfaceAsync).
This is not the type of the class firing the event!
 
Therefore, subscriber and publisher only need to know the topic string and the signature of the event. No hard references.
 
Happy coding
Urs
-^-^-^-^-^-^-^-
planetgeek.ch

QuestionSilverlight?memberDewey17 Nov '09 - 11:38 
Hi Urs,
 
I just discovered your great work, and wondered if there is any reason this couldn't be used in Silverlight?
 
BTW, I did download the latest from SourceForge. Did you ever consider putting this on Codeplex?
AnswerRe: Silverlight?memberUrs Enzler18 Nov '09 - 22:51 
Thanks!
 
I'm using the event broker in WPF applications without any problems. The synchronization with the dispatcher thread works out of the box.
Therefore, I'd say that it should work with Silverlight, too - but I don't have real evidence.
 
I'd be happy to hear about your experiences.
 
About Codeplex: If you can give me some good reasons to switch then I'll do it Wink | ;-)
 
Cheers
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralLicense agreementmembersakkels6 Aug '09 - 8:00 
Hi Urs
 
I have downloaded your event broker and I was very impressed with it. I am using it a home automation project. I am subscribed to a forum re the hardware I am using in my project and the moderator of the forum asked if I could put my C# source code onto the forum. Since I am using your event broker, am I allowed to post the event broker component (dll) on the forum so that my example can be run?
GeneralRe: License agreementmemberUrs Enzler6 Aug '09 - 11:30 
bbv.Common in licensed under the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html[^])
 
For short: you can redestribute bbv.Common as long as you pass a notice along, that bbv.Common is licensed under Apache 2.0.
 
If you change parts of the event broker then you have to be aware that parts of it contain code originally from CAB which is licensed under a special Microsoft license that requests a notice (in code) about this fact.
 
Therefore, add a notice file, write in there that bbv.Common is licensed under Apache License 2.0 and post it along with your code.
 
By the way, you may want to make sure that you use the latest version of the event broker that can be found at http://sourceforge.net/projects/bbvcommon/[^]
 
If you have any questions, requests or other feedback then feel free to ask here or on the project page on sourceforge.net.
 
Thanks for asking anyway.
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: License agreementmembersakkels10 Aug '09 - 23:57 
Thank you for your reply Urs. I will do so.
 
Just a question. I am firing the events directly i.e. eventBroker.Fire(...) rather than using the 'Publisher' way. Is there a disadvantage to directly fire the events? I have one event broker for the whole system.
 
Sakkie Smile | :)
GeneralRe: License agreementmemberUrs Enzler11 Aug '09 - 0:27 
There is a very small performance disadvantage due to additional object creation. However, this is really minimal.
 
The main disadvantage is that you introduce a direct coupling to the event broker: the class can then only be used with an event broker. If you use the Publisher way then the class can be used either with an event broker or just the plain old .net way. But, it's up to you to decide, which way suits you better.
 
We use the direct firing on the event broker only for objects that life very shortly (e.g. scheduled tasks that are created by a scheduler, executed and then disposed) because the register, fire, unregister for a single event would be overkill.
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: License agreementmembersakkels21 Dec '09 - 18:41 
Hi Urs,
 
I have a bug in my code and want to look at the logs that EventBroker generates. Where do I find the log? Does EventBroker log the basic stuff automatically or do I need to set something up?
 
Sakkie Smile | :)
GeneralRe: License agreementmemberUrs Enzler21 Dec '09 - 20:16 
Hi Sakkie
 
I'm just on my way to work, therfore I've got only a little time now (I will post a more detailed answer this evening).
 
For short:
- make sure that you use the current version from sourceforge (log was updated some time ago)
- configure log4net and set the log level to log everything (debug)
 
Without a correct log4net setup, the event broker will not log anything.
 
I'll post a sample this evening...
 
Have to go
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: License agreementmembersakkels21 Dec '09 - 21:37 
Thank you Urs!
AnswerRe: License agreementmemberUrs Enzler22 Dec '09 - 7:54 
Here you go:
 
Configure log4net by adding the following code in your main method:
log4net.Config.BasicConfigurator.Configure();
 
This will result in log messages written to the console (output window in Visual Studio)
 
Add the log extension to the event broker:
EventBroker eventBroker = new EventBroker();
 
// add log extension to the event broker to get log messages
eventBroker.AddExtension(new Extensions.LogExtension());
 
Finally, make sure that the log4net.dll is available in the folder where you run your application.
 
After that, the event broker will log quite a lot of messages to the console (event registrations, events processed, ...)
 
I'll update the version on sourceforge to include logging in the event broker sample application, soon.
 
Let me know if you have any problems!
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

RantPlease helpmembersakkels11 Jan '10 - 9:22 
Hi Urs
 
Thank you for your reply on the log. I have another issue. I get the following error when trying to register a subscriber:
"Subscriber handler has invalid signature: <object>"
 
The code snippet:
 
EventBroker _eventBroker = new EventBroker();
ClientConnectionHandler _clientConnectionHandler = new ClientConnectionHandler(_eventBroker);
_eventBroker.Register(_clientConnectionHandler);
 
If I try the following in the same position, it works!
 
Object x = new object();
_eventBroker.Register(x);
 
Thanks for your help
 
Sakkie
GeneralRe: Please helpmemberUrs Enzler11 Jan '10 - 19:30 
Hi Sakkie
 
Can you post or email me the code of the class ClientConnectionHandler (those members with [EventSubscription] attributes are enough (in case you dan't want to send me all the code of the class))?
There seams to be a problem with the declaration of a subscription because object is reported as declaring type in the error message, which is kind of weird.
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: Please helpmembersakkels11 Jan '10 - 19:38 
Hi Urs,
 
I had a blond moment. I think I have not defined the parameters for the EventSubscription correctly. I will first change this and see if it works. Thank you for pointing me in the correct direction and sorry for wasting your time.
 
Thanks again
Sakkie
GeneralRe: Please helpmemberUrs Enzler12 Jan '10 - 0:24 
No problem - glad I can help.
 
Let me know if the problem persists. And if you find the problem then please let me know what it was because the error message is really weird. Maybe I can provide a better error message for this scenario.
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: Please helpmembersakkels12 Jan '10 - 19:17 
Hi Urs,
 
It was what I expected. The parameter definitions for the function [Subscription] were wrong.
 
Sakkie
GeneralPreventing further events from executing if e.Cancel = true [modified]memberMusa Khan30 Jun '09 - 3:19 
Hi,
 
Terrific article!
 
My question is a about preventing further events from executing if e.Cancel = true.
 
I will use the following code snippet to explain the problem.
 
---- Event Publication code snippet start ----
 
[EventPublication(Constants.EventTopicNames.Core.Exiting,HandlerRestriction.Synchronous)]
public event EventHandler; Exiting;
 
---- Event Publication code snippet end ----
 

---- Subscription code snippet start ----
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.Publisher))]
public void OnExited1(object sender, CancelEventArgs e)
{
 
Console.WriteLine();
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.Publisher))]
public void OnExited2(object sender, CancelEventArgs e)
{
Console.WriteLine();
 
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.Publisher))]
public void OnExited3(object sender, CancelEventArgs e)
{
e.Cancel = true;
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.Publisher))]
public void OnExited4(object sender, CancelEventArgs e)
{
Console.WriteLine();
}
 
---- Subscription code snippet end ----
 
In the code above I have wired up 4 events, OnExited1, OnExited2, OnExited3, and OnExited4 which are fired in order when I close my application. As you can see in OnExited3 have set e.Cancel = true. My problem is event OnExited4 still fires, and I do not wish this to happen.
 
Further information if I inspect the value of e.Cancel in each event its is false until it is set to true in event OnExited3. In OnExited4 it is still true, so its state is persisted.
 
I know I could put an IF statement at the top of each event and prevent the rest of the code from executing if e.Cancel=true, however I am working on a UI framework, which will be consumed by other, module developers, so my question is: is there a generic solution to this problem? maybe by using something i've missed in the Event Broker? or by an extension to it?
 
Thanks in anticipation.
 
modified on Tuesday, June 30, 2009 9:27 AM

GeneralRe: Preventing further events from executing if e.Cancel = truememberUrs Enzler30 Jun '09 - 4:24 
You can use the NotAlreadyCanceled Matcher (bbv.Common.EventBroker.Matchers.NotAlreadyCanceled) as shown below:
 
[EventSubscription("topic", typeof(Handlers.Publisher), typeof(Matchers.NotAlreadyCanceled))]
public void Handler(object sender, CancelEventArgs e)
{
    // some great code that will only be executed if e.Cancel is equal to false
}
 
You can find a complete sample in the unit tests (bbv.Common.EventBroker.RestrictOnEventArgsTest in Assembly bbv.Common.EventBroker.Test).
 
Note that it can be tricky to rely on the sequence of event handlers called, although the event broker preserves the order of registration calls.
 
btw: I'm currently making some changes to the event broker and will probably release a new version in the next 2 weeks - check out at
http://sourceforge.net/projects/bbvcommon/[^]
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

GeneralRe: Preventing further events from executing if e.Cancel = truememberMusa Khan30 Jun '09 - 5:05 
Thanks for a very rapid response. With your help, my code is so very close to doing what I want.
 
The problem I’m now facing is: when I run my application, the match method on the NotAlreadyCanceled class fires 4 times BEFORE ANY line of code in the 4 events is executed.
 
I was rather expecting the match method to fire once for each event, just before the code lines within the event are executed. So if I stepped through the code to the point where it comes to firing event OnExited4, because e.Cancel is true at that point, the NotAlreadyCanceled.match check would ensure the code within OnExited4 is not executed.
 
What do i need to change to get the behavior I want?
 
For completeness here is the revised code:
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.UserInterface), typeof(Matchers.NotAlreadyCanceled))]
public void OnExited1(object sender, CancelEventArgs e)
{
 
Console.WriteLine();
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.UserInterface), typeof(Matchers.NotAlreadyCanceled))]
public void OnExited2(object sender, CancelEventArgs e)
{
Console.WriteLine();
 
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.UserInterface), typeof(Matchers.NotAlreadyCanceled))]
public void OnExited3(object sender, CancelEventArgs e)
{
e.Cancel = true;
}
 
[EventSubscription(Constants.EventTopicNames.Core.Exiting, typeof(Handlers.UserInterface), typeof(Matchers.NotAlreadyCanceled))]
public void OnExited4(object sender, CancelEventArgs e)
{
Console.WriteLine();
}
GeneralRe: Preventing further events from executing if e.Cancel = truememberUrs Enzler30 Jun '09 - 5:08 
I have to look into this. It should work as you expect it.
 
You'll hear from me tomorrow.
 
Cheers,
Urs
 
-^-^-^-^-^-^-^-
planetgeek.ch

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 26 Oct 2008
Article Copyright 2008 by Urs Enzler
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid