I am using events as a publisher/subscriber pattern in c#. However I dont know at design time how many publishers my program will be using. I would like to dynamically add events to either a class directly, or more plausibly to a collection/dictionary containing the events.
Are either of these scenarios possible using C#?
Create a mediator that your publishers publish to and that your subscribers subscribe to. For example:
public class Mediator
{
public static readonly Mediator Current = new Mediator();
public event EventHandler<EventArgs> EventRaised;
public void RaiseEvent(object sender, EventArgs eventArgs)
{
if (EventRaised!=null)
EventRaised(sender, eventArgs);
}
}
public class PublisherEventArgs : EventArgs
{
public string SomeData { get; set; }
}
public class Publisher
{
public void Publish(string data)
{
Mediator.Current.RaiseEvent(this, new PublisherEventArgs() { SomeData = data} );
}
}
public class Subscriber
{
public Subscriber()
{
Mediator.Current.EventRaised += HandlePublishedEvent;
}
private void HandlePublishedEvent(object sender, EventArgs e)
{
if(e is PublisherEventArgs)
{
string data = ((PublisherEventArgs)e).SomeData;
// todo: do something here
}
}
}
Make sure you implement IDisposable on your subscriber (its not in my example) so that it unsubscribes from the Mediator during dispose.
You'll need to disconnect the event from it's source in order to do this. This is commonly done with an event aggregator; it manages clients that want to publish events as well as those that want to subscribe to events. All of this decouples the publishers from the listeners and allows you to do what you are describing.
Prism has an event aggregator out-of-the-box that you can use in the form of the IEventAggregator interface.
Related
I'm creating an ASP.net Core application with onion architecture.I want to raise some events in Business Logic layer and subscribe to these events from infrastructure layer.(layers from inner to outer: Domain - Contracts - Business Logic - Infrastructure - API)
one of my BL classes and event implementation:
public class LiveStreamBusinessLogic : ILiveStreamBusinessLogic
{
public event ILiveStreamBusinessLogic.LiveStreamEventHandler LiveStreamEventOccured;
public async Task<IBusinessLogicResult<PagedList<LiveStreamForShowDto>>> GetAllLiveStreamAsync(LiveStreamParameters liveStreamParameters)
{
// some logic
OnDomainEventOccured();
return new BusinessLogicResult<PagedList<LiveStreamForShowDto>>
{Success = true, Result = livesListForTransferPaged};
}
protected virtual void OnDomainEventOccured()
{
LiveStreamEventOccured?.Invoke(this, EventArgs.Empty);
}
}
also i'm using DI for creating upper class with this interface :
public interface ILiveStreamBusinessLogic
{
public delegate void LiveStreamEventHandler(object sender, EventArgs args);
public event LiveStreamEventHandler LiveStreamEventOccured;
Task<IBusinessLogicResult<PagedList<LiveStreamForShowDto>>> GetAllLiveStreamAsync(LiveStreamParameters liveStreamParameters);
}
and this class will instantiated through StartUp class:
services.AddScoped<ILiveStreamBusinessLogic, LiveStreamBusinessLogic>();
and my subscriber is :
public class ElasticLogger
{
private readonly ILoggerManager _loggerManager;
private readonly ILiveStreamBusinessLogic _liveStreamBusinessLogic;
public ElasticLogger(ILoggerManager loggerManager, ILiveStreamBusinessLogic liveStreamBusinessLogic)
{
_loggerManager = loggerManager;
_liveStreamBusinessLogic = liveStreamBusinessLogic;
Subscribe();
}
private void Subscribe()
{
_liveStreamBusinessLogic.LiveStreamEventOccured += OnDomainEventOccured;
}
private void OnDomainEventOccured(object sender, EventArgs e)
{
_loggerManager.LogInfo(Serialize(e).ToString());
}
}
and StartUp :
services.AddScoped<ElasticLogger>();
the problem is event will raise correctly but the handler does not execute. I guess there is a problem with the procedure of instantiating my classes in startup but have no idea how to solve it? any solution or even better pattern for this problem?
By looking at your example codes here, I cannot see that you are creating an instance of the ElasticLogger. That means no ElasticLogger is created, therefore it couldn't Subscribe.
You can check if my theory is correct or not, by putting a breakpoint in the constructor of ElasticLogger. If you never hit the breakpoint, then I'm right.
I suggest you to refactor ElasticLogger, don't call Subscribe from the constructor. But do like this:
public class ElasticLogger
{
private readonly ILoggerManager _loggerManager;
private readonly ILiveStreamBusinessLogic _liveStreamBusinessLogic;
public ElasticLogger(ILoggerManager loggerManager, ILiveStreamBusinessLogic liveStreamBusinessLogic)
{
_loggerManager = loggerManager;
_liveStreamBusinessLogic = liveStreamBusinessLogic;
}
public void Subscribe()
{
_liveStreamBusinessLogic.LiveStreamEventOccured += OnDomainEventOccured;
}
private void OnDomainEventOccured(object sender, EventArgs e)
{
_loggerManager.LogInfo(Serialize(e).ToString());
}
}
But, make sure you call it externally, after your application starts, call it like: elasticLogger.Subscribe() externally. Then your event should be handled.
What is the best way or best practice to propagate events from a base class (and handle them at the base as well) to the inherited or implementing application - because I want all the code to execute from the base to the MyClientListener to the Winform ?
I have a [WCF DuplexClient] class which other [WCF ClientListener] classes will derive from. I want to make it reusable for all of my services. I have an event InnerChannel_Faulted - in this base class I have an initializer in the base class which subscribes to events and the base class will generally handle these as far as the WCF side of things goes. I want to also be able to have my specific ClientListener implementation to be able to provide additional functionality - behavior to those events - mostly for the Winforms Application.
Is my thinking right here - or do I need to regurgitate the events up the food chain so they will be available to the Winforms app ?
I have made the handlers in the base class like this:
class MyClient<T> :DuplexClientBase<T> where T : class
{
protected virtual void InitializeClient()
{
base.InnerChannel.Faulted += InnerChannel_Faulted;
}
protected virtual void InnerChannel_Faulted(object sender, EventArgs e)
{
// ... do something()
}
}
class MyListener : MyClient<MyListenerService>
{
public MyListener(){ // do stuff}
// .. other methods
}
WINDOWFORMAPP : FORM
{
private MyListener mylistener = new MyListener();
WINDOWFORMAPP()
{
// somehow subscribe to
mylistener.InnerChannel_Faulted +=
}
private override void InnerChannel_Faulted(object sender, EventArgs e)
{
// DoSomething to GUI - notifications GUI elements etc..
// then call.
mylistener.InnerChannel_Faulted()
}
}
It's not standard to subscribe to the event from the same class or subclass. The usual approach is to structure the code as:
public class MyClass {
public event EventHandler SomeAction;
private void DoStuff() {
bool fireAction = false;
//....
if (fireAction) {
EventArgs e = ...; // can be more specific if needed
OnSomeAction(e);
}
}
protected virtual void OnSomeAction(EventArgs e) {
if (SomeAction != null)
SomeAction(this, e);
}
}
public class MySubclass : MyClass {
protected override void OnSomeAction(EventArgs e) {
// code before event is triggered
base.OnSomeAction(e); // fires event to listeners
// code after event is triggered
}
}
Then in your form:
public class MyForm : Form {
MyClass mc = new MyClass();
public MyForm() {
mc.SomeAction += mc_SomeAction;
}
private void mc_SomeAction(Object sender, EventArgs e) {
//...
}
}
Im trying to implement an Event System for a game, where there are classes that can fire or handle an event wheter or not they implement these interfaces:
public interface IGameEvent<T> where T : EventArgs
{
event EventHandler<T> OnEvent;
}
public interface IGameHandler<T> where T : EventArgs
{
void OnEvent(object sender, T e);
}
everything looked great until i realized that no class can implement more than 1 IGameEvent
because it would cause duplicate declaration,
Here is an example:
public class Event
{
public KeyPressEvent OnKeyPress;
public UpdateEvent OnUpdate;
public void AddHadler<T>(IGameEvent<T> eEvent , IGameHandler<T> eHandler) where T : EventArgs
{
eEvent.OnEvent += eHandler.OnEvent;
}
public void RemoveHandler<T>(IGameEvent<T> eEvent, IGameHandler<T> eHandler) where T : EventArgs
{
eEvent.OnEvent -= eHandler.OnEvent;
}
}
KeyPressEvent:
public class KeyPressEvent : IGameEvent<KeyPressEvent.KeyPressedEventArgs>
{
public class KeyPressedEventArgs : EventArgs
{
public KeyPressedEventArgs(Keys key)
{
Key = key;
}
public Keys Key { get; private set; }
}
public event EventHandler<KeyPressedEventArgs> OnEvent;
private void OnCheckForKeyPressed() //Example
{
if (OnEvent != null)
OnEvent(this, new KeyPressedEventArgs(Keys.Space));
}
}
Would be better to manually store the suscribers in a list in the EventSystem ?
How slower or faster than this approach that would be?
Thanks!
The common approach is to implement events aggregator pattern. Google search will provide you with tons of different variations. For example, it might look like this (what i am currently using):
interface IEventsAggrgator
{
//fires an event, reperesented by specific message
void Publish<TMessage>(TMessage message);
//adds object to the list of subscribers
void Subscribe(object listener);
//remove object from the list of subscribers
void Unsubscribe(object listener);
}
interface IHandler<TMessage>
{
//implement this in subscribers to handle specific messages
void Handle(TMessage message);
}
I'm trying to find the best way to create a system where event sources can be added to a manager class, which will then re-dispatch their events to listeners. Specifically, I have many different input sources (keyboard input source, mouse input source, virtual keyboard input source, etc) and I'd like to allow developers to listen for, say, the KeyDown event on both the keyboard input source and the input manager itself (to catch this event from any active input source).
It's easy to brute-force a solution where I end up creating many "dispatch" functions, that simply re-dispatch events when they come through, but I end up having dozens of single line functions and I have to create new functions whenever a new event is added to an input source interface.
I've considered using lambdas, but I need a way to unhook the events if an input source is removed from the manager. I can keep the lambda in a dictionary, keyed by input source, but many of the events have different arg classes, and creating multiple dictionaries to do this starts to get ugly.
I'm wondering if I'm missing some simple way of doing this which keeps things clean and keeps the amount of additional code I need to write down.
For reference, here's a sample of the objects I'm working with:
public interface IInputSource {}
public interface IKeyboardInputSource : IInputSource
{
event EventHandler<KeyboardEventArgs> KeyDown;
event EventHandler<KeyboardEventArgs> KeyUp;
}
public interface IMouseInputSource : IInputSource
{
event EventHandler<MouseEventArgs> MouseDown;
event EventHandler<MouseEventArgs> MouseUp;
}
public class InputManager : IKeyboardInputSource, IMouseInputSource
{
private List<IInputSource> InputSources;
//Event declarations from IKeyboardInputSource and IMouseInputSource
public void AddSource(IInputSource source)
{
InputSources.Add(source);
if (source is IKeyboardInputSource)
{
var keyboardSource = source as IKeyboardInputSource;
keyboardSource.KeyDown += SendKeyDown;
// Listen for other keyboard events...
}
if (source is IMouseInputSource)
{
// Listen for mouse events...
}
}
public void RemoveSource(IInputSource source)
{
if (source is IKeyboardInputSource)
{
var keyboardSource = source as IKeyboardInputSource;
keyboardSource.KeyDown -= SendKeyDown;
// Remove other keyboard events...
}
if (source is IMouseInputSource)
{
// Remove mouse events...
}
InputSources.Remove(source);
}
private void SendKeyDown(object sender, KeyboardEventArgs e)
{
if (KeyDown != null)
KeyDown(sender, e);
}
//Other "send" functions
}
Have you looked at the Reactive Extensions (Rx) framework? Looks like it will what you are asking for and gives you a rich functional/lambda like api to manage and process events.
The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators
Probably something like this would help - it's a generic approach, with both direct event subscription or via 'sink' interface
interface IInputSource<T> where T : EventArgs
{
event EventHandler<T> InputEvent;
}
interface IInputSink<in T> where T : EventArgs
{
void InputMessageHandler(object sender, T eventArgs);
}
internal class InputManager
{
private Dictionary<Type, object> _inputSources;
private Dictionary<Type, object> _inputSinks;
private Dictionary<Type, object> _events;
public void AddSource<T>(IInputSource<T> source) where T : EventArgs
{
_inputSources[typeof(T)] = _inputSources; //add source
_events[typeof(T)] = (EventHandler<T>)Dispatch; //register event for subscribers
source.InputEvent += Dispatch;
source.InputEvent += Dispatch2;
}
// Dispatch trough direct event subscriptions;
private void Dispatch<T>(object sender, T e) where T : EventArgs
{
var handler = _events[typeof(T)] as EventHandler<T>;
handler.Invoke(sender, e);
}
// Dispatch trough IInputSink subscriptions;
private void Dispatch2<T>(object sender, T e) where T : EventArgs
{
var sink = _inputSinks[typeof(T)] as IInputSink<T>;
sink.InputMessageHandler(sender, e);
}
//Subscription: Client should provide handler into Subscribe()
//or subscribe with IInputSink<MyEvent> implementation (Subscribe2())
public void Subscribe<T>(EventHandler<T> handler) where T : EventArgs
{
var #event = _events[typeof(T)] as EventHandler<T>;
_events[typeof(T)] = #event + handler;
}
public void Subscribe2<T>(IInputSink<T> sink) where T : EventArgs
{
_inputSinks[typeof(T)] = sink;
}
}
class XXXX : EventArgs
{
}
public class Sink: IInputSink<XXXX>
{
#region Implementation of IInputSink<in XXXX>
public void InputMessageHandler(object sender, XXXX eventArgs)
{
throw new NotImplementedException();
}
#endregion
public Sink()
{
var v = new InputManager();
v.Subscribe<XXXX>(GetInputEvent);
v.Subscribe2(this);
}
private void GetInputEvent(object sender, XXXX xxxx)
{
throw new NotImplementedException();
}
}
I am currently having a hardtime understanding and implementing events in C# using delagates. I am used to the Java way of doing things:
Define an interface for a listener type which would contain a number of method definitions
Define adapter class for that interface to make things easier if I'm not interested in all the events defined in a listener
Define Add, Remove and Get[] methods in the class which raises the events
Define protected fire methods to do the dirty work of looping through the list of added listeners and calling the correct method
This I understand (and like!) - I know I could do this exactly the same in c#, but it seems that a new (better?) system is in place for c#. After reading countless tutorials explaining the use of delegates and events in c# I still am no closer to really understanding what is going on :S
In short, for the following methods how would I implement the event system in c#:
void computerStarted(Computer computer);
void computerStopped(Computer computer);
void computerReset(Computer computer);
void computerError(Computer computer, Exception error);
^ The above methods are taken from a Java application I once made which I'm trying to port over to c#.
Many many thanks!
You'd create four events, and methods to raise them, along with a new EventArgs-based class to indicate the error:
public class ExceptionEventArgs : EventArgs
{
private readonly Exception error;
public ExceptionEventArgs(Exception error)
{
this.error = error;
}
public Error
{
get { return error; }
}
}
public class Computer
{
public event EventHandler Started = delegate{};
public event EventHandler Stopped = delegate{};
public event EventHandler Reset = delegate{};
public event EventHandler<ExceptionEventArgs> Error = delegate{};
protected void OnStarted()
{
Started(this, EventArgs.Empty);
}
protected void OnStopped()
{
Stopped(this, EventArgs.Empty);
}
protected void OnReset()
{
Reset(this, EventArgs.Empty);
}
protected void OnError(Exception e)
{
Error(this, new ExceptionEventArgs(e));
}
}
Classes would then subscribe to the event using either a method or a an anonymous function:
someComputer.Started += StartEventHandler; // A method
someComputer.Stopped += delegate(object o, EventArgs e)
{
Console.WriteLine("{0} has started", o);
};
someComputer.Reset += (o, e) => Console.WriteLine("{0} has been reset");
A few things to note about the above:
The OnXXX methods are protected so that derived classes can raise the events. This isn't always necessary - do it as you see fit.
The delegate{} piece on each event declaration is just a trick to avoid having to do a null check. It's subscribing a no-op event handler to each event
The event declarations are field-like events. What's actually being created is both a variable and an event. Inside the class you see the variable; outside the class you see the event.
See my events/delegates article for much more detail on events.
You'll have to define a single delegate for that
public delegate void ComputerEvent(object sender, ComputerEventArgs e);
ComputerEventArgs would be defined like this:
public class ComputerEventArgs : EventArgs
{
// TODO wrap in properties
public Computer computer;
public Exception error;
public ComputerEventArgs(Computer aComputer, Exception anError)
{
computer = aComputer;
error = anError;
}
public ComputerEventArgs(Computer aComputer) : this(aComputer, null)
{
}
}
The class that fires the events would have these:
public YourClass
{
...
public event ComputerEvent ComputerStarted;
public event ComputerEvent ComputerStopped;
public event ComputerEvent ComputerReset;
public event ComputerEvent ComputerError;
...
}
This is how you assign handlers to the events:
YourClass obj = new YourClass();
obj.ComputerStarted += new ComputerEvent(your_computer_started_handler);
Your handler is:
private void ComputerStartedEventHandler(object sender, ComputerEventArgs e)
{
// do your thing.
}
The main difference is that in C# the events are not interface-based. Instead, the event publisher declares the delegate which you can think of as a function pointer (although not exactly the same :-)). The subscriber then implements the event prototype as a regular method and adds a new instance of the delegate to the event handler chain of the publisher. Read more about delegates and events.
You can also read short comparison of C# vs. Java events here.
First of all, there is a standard method signature in .Net that is typically used for events. The languages allow any sort of method signature at all to be used for events, and there are some experts who believe the convention is flawed (I mostly agree), but it is what it is and I will follow it for this example.
Create a class that will contain the event’s parameters (derived from EventArgs).
public class ComputerEventArgs : EventArgs
{
Computer computer;
// constructor, properties, etc.
}
Create a public event on the class that is to fire the event.
class ComputerEventGenerator // I picked a terrible name BTW.
{
public event EventHandler<ComputerEventArgs> ComputerStarted;
public event EventHandler<ComputerEventArgs> ComputerStopped;
public event EventHandler<ComputerEventArgs> ComputerReset;
...
}
Call the events.
class ComputerEventGenerator
{
...
private void OnComputerStarted(Computer computer)
{
EventHandler<ComputerEventArgs> temp = ComputerStarted;
if (temp != null) temp(this, new ComputerEventArgs(computer)); // replace "this" with null if the event is static
}
}
Attach a handler for the event.
void OnLoad()
{
ComputerEventGenerator computerEventGenerator = new ComputerEventGenerator();
computerEventGenerator.ComputerStarted += new EventHandler<ComputerEventArgs>(ComputerEventGenerator_ComputerStarted);
}
Create the handler you just attached (mostly by pressing the Tab key in VS).
private void ComputerEventGenerator_ComputerStarted(object sender, ComputerEventArgs args)
{
if (args.Computer.Name == "HAL9000")
ShutItDownNow(args.Computer);
}
Don't forget to detach the handler when you're done. (Forgetting to do this is the biggest source of memory leaks in C#!)
void OnClose()
{
ComputerEventGenerator.ComputerStarted -= ComputerEventGenerator_ComputerStarted;
}
And that's it!
EDIT: I honestly can't figure out why my numbered points all appear as "1." I hate computers.
there are several ways to do what you want. The most direct way would be to define delegates for each event in the hosting class, e.g.
public delegate void ComputerStartedDelegate(Computer computer);
protected event ComputerStartedDelegate ComputerStarted;
public void OnComputerStarted(Computer computer)
{
if (ComputerStarted != null)
{
ComputerStarted.Invoke(computer);
}
}
protected void someMethod()
{
//...
computer.Started = true; //or whatever
OnComputerStarted(computer);
//...
}
any object may 'listen' for this event simply by:
Computer comp = new Computer();
comp.ComputerStarted += new ComputerStartedDelegate(
this.ComputerStartedHandler);
protected void ComputerStartedHandler(Computer computer)
{
//do something
}
The 'recommended standard way' of doing this would be to define a subclass of EventArgs to hold the Computer (and old/new state and exception) value(s), reducing 4 delegates to one. In this case that would be a cleaner solution, esp. with an Enum for the computer states in case of later expansion. But the basic technique remains the same:
the delegate defines the signature/interface for the event handler/listener
the event data member is a list of 'listeners'
listeners are removed using the -= syntax instead of +=
In c# events are delegates. They behave in a similar way to a function pointer in C/C++ but are actual classes derived from System.Delegate.
In this case, create a custom EventArgs class to pass the Computer object.
public class ComputerEventArgs : EventArgs
{
private Computer _computer;
public ComputerEventArgs(Computer computer) {
_computer = computer;
}
public Computer Computer { get { return _computer; } }
}
Then expose the events from the producer:
public class ComputerEventProducer
{
public event EventHandler<ComputerEventArgs> Started;
public event EventHandler<ComputerEventArgs> Stopped;
public event EventHandler<ComputerEventArgs> Reset;
public event EventHandler<ComputerEventArgs> Error;
/*
// Invokes the Started event */
private void OnStarted(Computer computer) {
if( Started != null ) {
Started(this, new ComputerEventArgs(computer));
}
}
// Add OnStopped, OnReset and OnError
}
The consumer of the events then binds a handler function to each event on the consumer.
public class ComputerEventConsumer
{
public void ComputerEventConsumer(ComputerEventProducer producer) {
producer.Started += new EventHandler<ComputerEventArgs>(ComputerStarted);
// Add other event handlers
}
private void ComputerStarted(object sender, ComputerEventArgs e) {
}
}
When the ComputerEventProducer calls OnStarted the Started event is invoked which in turn will call the ComputerEventConsumer.ComputerStarted method.
The delegate declares a function signature, and when it's used as an event on a class it also acts as a collection of enlisted call targets. The += and -= syntax on an event is used to adding a target to the list.
Given the following delegates used as events:
// arguments for events
public class ComputerEventArgs : EventArgs
{
public Computer Computer { get; set; }
}
public class ComputerErrorEventArgs : ComputerEventArgs
{
public Exception Error { get; set; }
}
// delegates for events
public delegate void ComputerEventHandler(object sender, ComputerEventArgs e);
public delegate void ComputerErrorEventHandler(object sender, ComputerErrorEventArgs e);
// component that raises events
public class Thing
{
public event ComputerEventHandler Started;
public event ComputerEventHandler Stopped;
public event ComputerEventHandler Reset;
public event ComputerErrorEventHandler Error;
}
You would subscribe to those events with the following:
class Program
{
static void Main(string[] args)
{
var thing = new Thing();
thing.Started += thing_Started;
}
static void thing_Started(object sender, ComputerEventArgs e)
{
throw new NotImplementedException();
}
}
Although the arguments could be anything, the object sender and EventArgs e is a convention that's used very consistently. The += thing_started will first create an instance of the delegate pointing to target method, then add it to the event.
On the component itself you would typically add methods to fire the events:
public class Thing
{
public event ComputerEventHandler Started;
public void OnStarted(Computer computer)
{
if (Started != null)
Started(this, new ComputerEventArgs {Computer = computer});
}
}
You must test for null in case no delegates have been added to the event. When you make the method call however all delegates which have been added will be called. This is why for events the return type is void - there is no single return value - so to feed back information you would have properties on the EventArgs which the event handlers would alter.
Another refinement would be to use the generic EventHandler delegate rather than declaring a concrete delegate for each type of args.
public class Thing
{
public event EventHandler<ComputerEventArgs> Started;
public event EventHandler<ComputerEventArgs> Stopped;
public event EventHandler<ComputerEventArgs> Reset;
public event EventHandler<ComputerErrorEventArgs> Error;
}
Thank you all so much for your answers! Finally I'm starting to understand what is going on. Just one thing; It seems that if each event had a different number/type of arguments I'd need to create a different :: EventArgs class to deal with it:
public void computerStarted(Computer computer);
public void computerStopped(Computer computer);
public void computerReset(Computer computer);
public void breakPointHit(Computer computer, int breakpoint);
public void computerError(Computer computer, Exception exception);
This would require three classses to deal with the events!? (Well two custom, and one using the default EventArgs.Empty class)
Cheers!
Ok, FINAL clarification!: So this is pretty much the best I can do code-wise to implement those events?
public class Computer {
public event EventHandler Started;
public event EventHandler Stopped;
public event EventHandler Reset;
public event EventHandler<BreakPointEvent> BreakPointHit;
public event EventHandler<ExceptionEvent> Error;
public Computer() {
Started = delegate { };
Stopped = delegate { };
Reset = delegate { };
BreakPointHit = delegate { };
Error = delegate { };
}
protected void OnStarted() {
Started(this, EventArgs.Empty);
}
protected void OnStopped() {
Stopped(this, EventArgs.Empty);
}
protected void OnReset() {
Reset(this, EventArgs.Empty);
}
protected void OnBreakPointHit(int breakPoint) {
BreakPointHit(this, new BreakPointEvent(breakPoint));
}
protected void OnError(System.Exception exception) {
Error(this, new ExceptionEvent(exception));
}
}
}