public class RSensor : IRSensor
{
public RSensorType SensorType { get; protected set; }
public event EventHandler ConnectionLost;
public void Configure(Stream input, Stream output, RSensorType type, ISensorReciever reciever)
{
throw new NotImplementedException();
}
public RSensor()
{
}
}
I have a class RSensor that has an EventHandler ConnectionLost which will inform me when the connection goes down.
I have another class ConnectionManager that somehow needs to handle when the connection goes down. I have created a dummy function void HandleConnectionLost()
in this class. How do I trigger this function when the EventHandler ConnectionLost from RSensor class is triggered.
public class ConnectionManager
{
ActiveList m_ActiveList;
Dictionary<IRionSensor, VSManager> m_ConnectionManager;
class VehicleStreamManager
{
public IVehicle Vehicle { get; set; }
public NetworkStream AStream { get; set; }
public NetworkStream BStream { get; set; }
}
ConnectionManager(ActiveExercise exercise)
{
m_ActiveList = exercise;
m_ConnectionManager = new Dictionary<IRSensor, VehicleStreamManager>();
}
void Connect()
{
List<VehicleStreamManager> vsmList;
VehicleStreamManager vsm;
vsm = InitiateAVehicleConnections();
m_ConnectionManager.Add(null, vsm);
vsmList = InitiateBVehicleConnections();
foreach(var item in vsmList)
{
RSensor fsensor = new RSensor();
fsensor.Configure(item.AStream, item.BStream, RSensorType.RSensor_Both, null);
m_ConnectionManager.Add(fsensor, item);
}
}
void HandleConnectionLost()
{
//Do some stuff
}
}
}
You need to redefine your HandleConnectionLost handler slightly, so that it conforms to an EventHandler signature:
void HandleConnectionLost(object sender, EventArgs args)
{
// Do stuff here
}
Then, in your ConnectionManager loop that instantiates sensors, you need to wire up the event handlers:
foreach(var item in vsmList)
{
RSensor fsensor = new RSensor();
fsensor.Configure(item.AStream, item.BStream,
RSensorType.RSensor_Both, null);
fsensor.ConnectionLost += HandleConnectionLost;
m_ConnectionManager.Add(fsensor, item);
}
This way, you handler will be triggered whenever one of the sensors loses the connection.
You are not showing the code that does this, but you said that ConnectionLost event will inform me when the connection goes down. I take this to mean that there is code present that raises the event already. If not, let me know and I'll extend the example.
However, the sensor must rely on some kind of external notification of the connection being lost - it will likely rely on a lower-level infrastructure.
Related
I am using the observer pattern to add and remove subscribers from a newsletter using events.
I'm not sure how to approach what I'm trying to do. Is it possible to add a subscriber using an event and how?
The console is operated by a form with buttons so when the button is clicked it will add subscribers and when the remove button is clicked it will remove a subscriber, on the form, there is also a button to post a newsletter which will post a newsletter for each subscriber.
This is what I have managed to get so far:
class Program
{
//[STAThread]
static void Main(string[] args)
{
SoftwareRevolution softrev = new Ass_3._1.SoftwareRevolution();
ConsoleOutput First = new ConsoleOutput(softrev);
softrev.Datetime = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new InputForm());
}
}
public delegate void NotifyMe(string Value);
class ConsoleOutput : IEventsObserver
{
IEventsSubject IEventsSubject;
public ConsoleOutput(IEventsSubject IEventsSubject)
{
this.IEventsSubject = IEventsSubject;
this.IEventsSubject.Notifier += new Ass_3._1.NotifyMe(UpdateNews);
}
public void UpdateNews(string info)
{
Console.WriteLine(info);
}
}
interface IEventsObserver
{
void UpdateNews(string info);
}
interface IEventsSubject
{
event NotifyMe Notifier;
}
class SoftwareRevolution : IEventsSubject
{
List<IEventsObserver> Readers = new List<IEventsObserver>();
private string datetime;
public string Datetime
{
get
{
return datetime;
}
set
{
datetime = value;
Notifier(datetime);
}
}
public event NotifyMe Notifier;
}
The object which issues a newsletter, should have an event which fires when a newsletter issues. Then all subscribes which has subscribed for that event will receive it.
Distribution of event will be done without having such list in publisher class. In fact the delegate implementation in C# takes care of that and there is an invokation list behind the event delegate.
Usually the Publisher doesn't need to keep list of Subscriber object itself and if you need such list, it's better to keep it in a SubscriptionManager.
The subscription manager, subscribes and unsubscribes the subscribers to the event of publisher. It also can keep a list of subscribers.
Example
The Newsletter class contains some fields which represents a newsletter:
public class Newsletter
{
public string Content;
}
The NewsLetterPublishedEventArgs contains information about published newsletter:
public class NewsletterPublishedEventArgs : EventArgs
{
public Newsletter Newsletter { get; set; }
}
The Publisher class published the newsletter and raises an event after publishing:
public class Publisher
{
public event EventHandler<NewsletterPublishedEventArgs> NewsLetterPublished;
public void PublishNewsLetter()
{
var newsLetter = new Newsletter() { Content = $"New publish at {DateTime.Now}" };
NewsLetterPublished?.Invoke(this,
new NewsletterPublishedEventArgs() { Newsletter = newsLetter });
}
}
The Subscriber class has a method which allows it to receive NewsLetterPublished notification:
public class Subscriber
{
public string Name { get; set; }
public void ReceiveNewsLetter(object sender, NewsletterPublishedEventArgs e)
{
MessageBox.Show(e.Newsletter.Content);
}
}
At the end, SubscriptionManager class subscribes and unsubscribes subscribers to the publisher:
public class SubscriptionManager
{
public Publisher Publisher => new Publisher();
private List<Subscriber> subscribers;
public void Subscribe(Subscriber s)
{
if (!subscribers.Contains(s))
{
subscribers.Add(s);
Publisher.NewsLetterPublished += s.ReceiveNewsLetter;
}
}
public void Unsubscribe(Subscriber s)
{
if (subscribers.Contains(s))
{
subscribers.Remove(s);
Publisher.NewsLetterPublished -= s.ReceiveNewsLetter;
}
}
}
Note
To keep thing simple I created a simple example to just demonstrate the logic for learning purpose. In a real world example, you need to use interfaces, generic classes and dependency injection.
I'm used to using delegate EventHandler for event callbacks but now I'm attempting to use event Action for invoking events. I couldn't find much info on how this can be used properly anywhere so I'm hoping someone can point me in the right direction.
I have an Action event handler that handles string objects. In my subscriber class I have public event Action<string> UploadProgress;. The event handler is invoked like this:
UploadProgress.Invoke(string.Format("sending file data {0:0.000}%", (bytesSoFar * 100.0f) / totalToUpload));
The listener class is subscribed to this event as below:
uploadFile.UploadProgress += uploadFile_UploadProgress;
void uploadFile_UploadProgress(string obj)
{
var prog = obj;
}
When the event is invoked, I get System.NullReferenceException: Object reference not set to an instance of an object. I'm not sure what I need to change in the subscriber class to avoid this error. Can someone tell me the proper way to use event Action or provide me the link to where I can read up on it? I know how to use the normal Action but confused about declaring it as an event. Any help is appreciated.
This way is much better, send bytesToUpload and totalToUpload through event, instead of the whole Action (right sample):
internal class Program
{
private static void Main(string[] args)
{
SomeClass someClass = new SomeClass();
someClass.UploadProgress += SomeClass_UploadProgress;
someClass.DoSomeUpload();
}
private static void SomeClass_UploadProgress(object sender, UploadEventArgs e)
{
string s = string.Format("sending file data {0:0.000}%", (e.BytesSoFar * 100.0f) / e.TotalToUpload);
Console.WriteLine(s);
}
}
public class UploadEventArgs : EventArgs
{
public float BytesSoFar { get; set; }
public float TotalToUpload { get; set; }
}
public class SomeClass
{
public event EventHandler<UploadEventArgs> UploadProgress;
public void DoSomeUpload()
{
if (UploadProgress != null)
{
UploadEventArgs e = new UploadEventArgs();
e.BytesSoFar = 123f;
e.TotalToUpload = 100000f;
UploadProgress.Invoke(this, e);
}
}
}
I have an enumeration prior.
Each of my scripts has a property priority of prior type. (Every script has its own class)
I have a data provider, which can send events every frame.
I want a script to subscribe only to an event which has arguments with priority equal to the script's one.
For example, a script with moderate priority should receive only events with moderate parameter of event arguments
prior has too many members to create a special event argument class for each.
Unfortunately:
a)I know only how to subscribe to a certain event type.
b)I can't make a generic class for event arguments, because elements of enum are not types
How can I do it?
The project currently looks this way:
public class TDefault:MonoBehaviour,IDefault
{
public enum prior
{
none,
...,
terminal
};
prior priority;
public virtual void apply()//For override by scripts
{
}
void Start()
{
//There should be adding a method which calls apply() when event_manager
//sends Event with a certain priority
}
public TDefault ()
{
if(essential==null)
essential=new TEssential();
}
}
public class TApplyEventParam : EventArgs
{
public TDefault.prior priority;
public TApplyEventParam(TDefault.prior _priority)
{
priority=_priority;
}
}
public class event_manager : TDefault
{
//This has fixed type
event EventHandler<TApplyEventParam> handler=new EventHandler<TApplyEventParam>();
void Update ()
{
foreach (prior p in (prior[]) Enum.GetValues(typeof(prior)))
{
handler(this,new TApplyEventParam(p));
}
}
}
The problem you're dealing with, if I understood it correctly, is that you would like to have your event subscription conditionally called depending on the event payload (the priority value inside the TApplyEventParam). That is something that you cannot do which results in you having to filter out the unwanted events inside your event handler like proposed by #Henk-Holterman
Another approach could be to skip the usage of events and maintain your own list of subscribers inside the data provider.
Based on the terminology used by you in your question (not the code example) you could do something like this:
using System;
using System.Collections.Generic;
namespace Example
{
public enum Prior
{
None,
Moderate,
Terminal
};
public abstract class ScriptBase
{
public abstract Prior Prior { get; }
public abstract void Apply();
public void Start(DataProvider dataProvider)
{
dataProvider.Subscribe(Prior, Apply);
}
public void Stop(DataProvider dataProvider)
{
dataProvider.Unsubscribe(Prior, Apply);
}
}
public class ScriptHandlingModerateEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Moderate; }
}
public override void Apply()
{
Console.WriteLine("Handling moderate event by " + GetType().Name);
}
}
public class ScriptHandlingTerminalEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Terminal; }
}
public override void Apply()
{
Console.WriteLine("Handling terminal event by " + GetType().Name);
}
}
public class DataProvider
{
private readonly Dictionary<Prior, List<Action>> _subscribersByPrior;
public DataProvider()
{
_subscribersByPrior = new Dictionary<Prior, List<Action>>();
foreach (Prior prior in (Prior[])Enum.GetValues(typeof(Prior)))
{
_subscribersByPrior.Add(prior, new List<Action>());
}
}
public void Subscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Add(action);
}
public void Unsubscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Remove(action);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var subscriber in _subscribersByPrior[prior])
{
subscriber();
}
}
}
public static class Program
{
public static void Main()
{
DataProvider dataProvider = new DataProvider();
var scriptHandlingModerateEvents = new ScriptHandlingModerateEvents();
scriptHandlingModerateEvents.Start(dataProvider);
var scriptHandlingTerminalEvents = new ScriptHandlingTerminalEvents();
scriptHandlingTerminalEvents.Start(dataProvider);
for (int i = 0; i < 10; i++)
{
dataProvider.DoSomethingThatTriggersPriorEvents(i);
}
scriptHandlingTerminalEvents.Stop(dataProvider);
scriptHandlingModerateEvents.Stop(dataProvider);
Console.WriteLine();
}
}
}
this way the DataProvider is not aware of scripts, but if that is not an issue, you could maintain a list of ScriptBase instances and check the Prior property inside the
DoSomethingThatTriggersPriorEvents like this:
public class DataProvider2
{
private readonly List<ScriptBase> _scripts = new List<ScriptBase>();
public void Subscribe(ScriptBase script)
{
_scripts.Add(script);
}
public void Unsubscribe(ScriptBase script)
{
_scripts.Remove(script);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var script in _scripts)
{
if (script.Prior == prior)
{
script.Apply();
}
}
}
}
Goal: To change a image on a form when either udp or tcp uses its send method
Problem: I have no idea how to get the event, eventhandler and delegates set up correctly
Send Interface
interface ISendData
{
void Send();
}
Tcp Connection class
//Need some type of delegate??
public class TCPconnection : ISendData
{
void Send()
{
//how invoke/fire a send Event?
}
}
UDP Connection class
//Need some type of delegate??
public class UDPConnection : ISendData
{
void Send()
{
//how invoke/fire a send event?
}
}
the winform which 'should' subscribe to seeing the fired events
public class myForm
{
private DataWatcher datawatcher = new DataWatcher();
private Image statusIndicator = null;
public myform()
{
initComponents();
datawatcher.DataSendActive += new DataWatcherSendHandler(DataSending);
datawatcher.DataSendInactive += new DataWatcherSendHandler(NoDataSending);
}
public void DataSending(object sender, DataWatcherArgs e)
{
statusIndicator = Properties.resources.greenLight;
}
public void NoDataSending(object sender, DataWatcherArgs e)
{
statusIndicator = Properties.resources.redLight;
}
}
The Event/Event handler?? But I really have no Idea what I'm doing here to make this work
public delegate void EventHandler(object sender, EventArgs e);
class DataWatcher
{
public event EventHandler DataSendActive;
public event EventHandler DataSendInactive;
protected virtual void onDataSendActive(System.EventArgs e)
{
if (DataSendActive != null)
{
DataSendActive(this, e);
}
}
protected virtual void onDataSendInactive(System.EventArgs e)
{
if (DataSendInactive != null)
{
DataSendInactive(this, e);
}
}
}
There are many conventions used to do this. Here's my little implementation.
public enum ActivityState
{
Sending,
Receiving,
Idle
}
public interface IDataTransferManager
{
// This event will fire when the activity state changes.
// note that Action<T> is introduced in .NET 3.5
// if you're using .NET 2.0, you can use a delegate.
event Action<ActivityState> DataActivityStateChange;
void Send(byte[] data);
//byte[] Receive();
// ... more methods ... //
}
Now the TcpConnection class will implement this.
public class TcpConnection : IDataTransferManager
{
public event Action<ActivityState> DataActivityStateChange;
public void Send(byte[] data)
{
// we're sending data. fire the change event
FireDataActivityStateChange(ActivityState.Sending);
//TODO: send the data
// we're done sending. Fire the change event
FireDataActivityStateChange(ActivityState.Idle);
}
private void FireDataActivityStateChange(ActivityState state)
{
// helper method, so I don't have to check the event
// to avoid null reference exceptions.
if (DataActivityStateChange != null)
DataActivityStateChange(state);
}
}
Here's the setup for your Form.
class MyForm // :Form
{
IDataTransferManager dataManager;
public MyForm()
{ // here, usually an instance will be passed in,
// so there's only one instance throughout the application.
// let's new up an instance for explanation purposes.
dataManager = new TcpConnection();
dataManager.DataActivityStateChange += (state) =>
{
// NOTE: if you don't like inline,
// you can point this labda to a method.
switch (state)
{
case ActivityState.Sending:
// change the image to the spinning toilet ball
break;
case ActivityState.Receiving:
// change the image to the spinning toilet ball, but reverse :P
break;
case ActivityState.Idle:
// hide it ?
break;
}
};
}
}
Here is a simple example of how you could implement an event for sending and not sending and subscribe to it
public class Connection
{
//Set up an event
public event EventHandler DataSending;
public event EventHandler DataNotSending
//This method will trigger the event for sending
private void OnDataSending()
{
if (DataSending!= null) { DataSending(this, EventArgs.Empty); }
}
//this method will trigger the event for finished sending
private void OnDataNotSending()
{
if (DataNotSending!= null) { DataNotSending(this, EventArgs.Empty); }
}
//This method performs your send logic
public void Send()
{
//Call your method that tells the event to be raised
OnDataSending();
//Then put your send code
OnDataNotSending(); //we're done!
}
}
This is how you use it in a consuming program
public class myForm
{
//This method is the one that sets up the
//instance and subscribes to the event
public myForm()
{
Connection con = new Connection();
con.DataSending += new EventHandler(con_DataSending);
con.DataNotSending += new EventHander(con_DataNotSending);
}
void con_DataSending(object sender, EventArgs e)
{
//Put your subscription logic here.
//Whatever you want to do in response to a send
}
void con_DataNotSending(object sender, EventArgs e)
{
//Put your subscription logic here.
//Respond to it not sending
}
}
I recently started digging into C# but I can't by my life figure out how delegates work when implementing the observer/observable pattern in the language.
Could someone give me a super-simple example of how it is done? I have googled this, but all of the examples I found were either too problem-specific or too "bloated".
The observer pattern is usually implemented with events.
Here's an example:
using System;
class Observable
{
public event EventHandler SomethingHappened;
public void DoSomething() =>
SomethingHappened?.Invoke(this, EventArgs.Empty);
}
class Observer
{
public void HandleEvent(object sender, EventArgs args)
{
Console.WriteLine("Something happened to " + sender);
}
}
class Test
{
static void Main()
{
Observable observable = new Observable();
Observer observer = new Observer();
observable.SomethingHappened += observer.HandleEvent;
observable.DoSomething();
}
}
See the linked article for a lot more detail.
Note that the above example uses C# 6 null-conditional operator to implement DoSomething safely to handle cases where SomethingHappened has not been subscribed to, and is therefore null. If you're using an older version of C#, you'd need code like this:
public void DoSomething()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
In this model, you have publishers who will do some logic and publish an "event."
Publishers will then send out their event only to subscribers who have subscribed to receive the specific event.
In C#, any object can publish a set of events to which other applications can subscribe.
When the publishing class raises an event, all the subscribed applications are notified.
The following figure shows this mechanism.
Simplest Example possible on Events and Delegates in C#:
code is self explanatory, Also I've added the comments to clear out the code.
using System;
public class Publisher //main publisher class which will invoke methods of all subscriber classes
{
public delegate void TickHandler(Publisher m, EventArgs e); //declaring a delegate
public TickHandler Tick; //creating an object of delegate
public EventArgs e = null; //set 2nd paramter empty
public void Start() //starting point of thread
{
while (true)
{
System.Threading.Thread.Sleep(300);
if (Tick != null) //check if delegate object points to any listener classes method
{
Tick(this, e); //if it points i.e. not null then invoke that method!
}
}
}
}
public class Subscriber1 //1st subscriber class
{
public void Subscribe(Publisher m) //get the object of pubisher class
{
m.Tick += HeardIt; //attach listener class method to publisher class delegate object
}
private void HeardIt(Publisher m, EventArgs e) //subscriber class method
{
System.Console.WriteLine("Heard It by Listener");
}
}
public class Subscriber2 //2nd subscriber class
{
public void Subscribe2(Publisher m) //get the object of pubisher class
{
m.Tick += HeardIt; //attach listener class method to publisher class delegate object
}
private void HeardIt(Publisher m, EventArgs e) //subscriber class method
{
System.Console.WriteLine("Heard It by Listener2");
}
}
class Test
{
static void Main()
{
Publisher m = new Publisher(); //create an object of publisher class which will later be passed on subscriber classes
Subscriber1 l = new Subscriber1(); //create object of 1st subscriber class
Subscriber2 l2 = new Subscriber2(); //create object of 2nd subscriber class
l.Subscribe(m); //we pass object of publisher class to access delegate of publisher class
l2.Subscribe2(m); //we pass object of publisher class to access delegate of publisher class
m.Start(); //starting point of publisher class
}
}
Output:
Heard It by Listener
Heard It by Listener2
Heard It by Listener
Heard It by Listener2
Heard It by Listener
.
.
.
(infinite times)
Here's a simple example:
public class ObservableClass
{
private Int32 _Value;
public Int32 Value
{
get { return _Value; }
set
{
if (_Value != value)
{
_Value = value;
OnValueChanged();
}
}
}
public event EventHandler ValueChanged;
protected void OnValueChanged()
{
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
}
public class ObserverClass
{
public ObserverClass(ObservableClass observable)
{
observable.ValueChanged += TheValueChanged;
}
private void TheValueChanged(Object sender, EventArgs e)
{
Console.Out.WriteLine("Value changed to " +
((ObservableClass)sender).Value);
}
}
public class Program
{
public static void Main()
{
ObservableClass observable = new ObservableClass();
ObserverClass observer = new ObserverClass(observable);
observable.Value = 10;
}
}
Note:
This violates a rule in that I don't unhook the observer from the observable, this is perhaps good enough for this simple example, but make sure you don't keep observers hanging off of your events like that. A way to handle this would be to make ObserverClass IDisposable, and let the .Dispose method do the opposite of the code in the constructor
No error-checking performed, at least a null-check should be done in the constructor of the ObserverClass
I've tied together a couple of the great examples above (thank you as always to Mr. Skeet and Mr. Karlsen) to include a couple of different Observables and utilized an interface to keep track of them in the Observer and allowed the Observer to to "observe" any number of Observables via an internal list:
namespace ObservablePattern
{
using System;
using System.Collections.Generic;
internal static class Program
{
private static void Main()
{
var observable = new Observable();
var anotherObservable = new AnotherObservable();
using (IObserver observer = new Observer(observable))
{
observable.DoSomething();
observer.Add(anotherObservable);
anotherObservable.DoSomething();
}
Console.ReadLine();
}
}
internal interface IObservable
{
event EventHandler SomethingHappened;
}
internal sealed class Observable : IObservable
{
public event EventHandler SomethingHappened;
public void DoSomething()
{
var handler = this.SomethingHappened;
Console.WriteLine("About to do something.");
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
internal sealed class AnotherObservable : IObservable
{
public event EventHandler SomethingHappened;
public void DoSomething()
{
var handler = this.SomethingHappened;
Console.WriteLine("About to do something different.");
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
internal interface IObserver : IDisposable
{
void Add(IObservable observable);
void Remove(IObservable observable);
}
internal sealed class Observer : IObserver
{
private readonly Lazy<IList<IObservable>> observables =
new Lazy<IList<IObservable>>(() => new List<IObservable>());
public Observer()
{
}
public Observer(IObservable observable) : this()
{
this.Add(observable);
}
public void Add(IObservable observable)
{
if (observable == null)
{
return;
}
lock (this.observables)
{
this.observables.Value.Add(observable);
observable.SomethingHappened += HandleEvent;
}
}
public void Remove(IObservable observable)
{
if (observable == null)
{
return;
}
lock (this.observables)
{
observable.SomethingHappened -= HandleEvent;
this.observables.Value.Remove(observable);
}
}
public void Dispose()
{
for (var i = this.observables.Value.Count - 1; i >= 0; i--)
{
this.Remove(this.observables.Value[i]);
}
}
private static void HandleEvent(object sender, EventArgs args)
{
Console.WriteLine("Something happened to " + sender);
}
}
}
Applying the Observer Pattern with delegates and events in c# is named "Event Pattern" according to MSDN which is a slight variation.
In this Article you will find well structured examples of how to apply the pattern in c# both the classic way and using delegates and events.
Exploring the Observer Design Pattern
public class Stock
{
//declare a delegate for the event
public delegate void AskPriceChangedHandler(object sender,
AskPriceChangedEventArgs e);
//declare the event using the delegate
public event AskPriceChangedHandler AskPriceChanged;
//instance variable for ask price
object _askPrice;
//property for ask price
public object AskPrice
{
set
{
//set the instance variable
_askPrice = value;
//fire the event
OnAskPriceChanged();
}
}//AskPrice property
//method to fire event delegate with proper name
protected void OnAskPriceChanged()
{
AskPriceChanged(this, new AskPriceChangedEventArgs(_askPrice));
}//AskPriceChanged
}//Stock class
//specialized event class for the askpricechanged event
public class AskPriceChangedEventArgs : EventArgs
{
//instance variable to store the ask price
private object _askPrice;
//constructor that sets askprice
public AskPriceChangedEventArgs(object askPrice) { _askPrice = askPrice; }
//public property for the ask price
public object AskPrice { get { return _askPrice; } }
}//AskPriceChangedEventArgs
/**********************Simple Example ***********************/
class Program
{
static void Main(string[] args)
{
Parent p = new Parent();
}
}
////////////////////////////////////////////
public delegate void DelegateName(string data);
class Child
{
public event DelegateName delegateName;
public void call()
{
delegateName("Narottam");
}
}
///////////////////////////////////////////
class Parent
{
public Parent()
{
Child c = new Child();
c.delegateName += new DelegateName(print);
//or like this
//c.delegateName += print;
c.call();
}
public void print(string name)
{
Console.WriteLine("yes we got the name : " + name);
}
}
I did't want to change my source code to add additional observer , so I have written following simple example:
//EVENT DRIVEN OBSERVER PATTERN
public class Publisher
{
public Publisher()
{
var observable = new Observable();
observable.PublishData("Hello World!");
}
}
//Server will send data to this class's PublishData method
public class Observable
{
public event Receive OnReceive;
public void PublishData(string data)
{
//Add all the observer below
//1st observer
IObserver iObserver = new Observer1();
this.OnReceive += iObserver.ReceiveData;
//2nd observer
IObserver iObserver2 = new Observer2();
this.OnReceive += iObserver2.ReceiveData;
//publish data
var handler = OnReceive;
if (handler != null)
{
handler(data);
}
}
}
public interface IObserver
{
void ReceiveData(string data);
}
//Observer example
public class Observer1 : IObserver
{
public void ReceiveData(string data)
{
//sample observers does nothing with data :)
}
}
public class Observer2 : IObserver
{
public void ReceiveData(string data)
{
//sample observers does nothing with data :)
}
}
Something like this:
// interface implementation publisher
public delegate void eiSubjectEventHandler(eiSubject subject);
public interface eiSubject
{
event eiSubjectEventHandler OnUpdate;
void GenereteEventUpdate();
}
// class implementation publisher
class ecSubject : eiSubject
{
private event eiSubjectEventHandler _OnUpdate = null;
public event eiSubjectEventHandler OnUpdate
{
add
{
lock (this)
{
_OnUpdate -= value;
_OnUpdate += value;
}
}
remove { lock (this) { _OnUpdate -= value; } }
}
public void GenereteEventUpdate()
{
eiSubjectEventHandler handler = _OnUpdate;
if (handler != null)
{
handler(this);
}
}
}
// interface implementation subscriber
public interface eiObserver
{
void DoOnUpdate(eiSubject subject);
}
// class implementation subscriber
class ecObserver : eiObserver
{
public virtual void DoOnUpdate(eiSubject subject)
{
}
}
.
observer pattern C# with event
.
link to the repository