Multiple events for one delegate - c#

NOTE; Posting Pseudo Code Example... See Example Text below ( I told you this would be a hilarious mess ! )
Class Enter
{
public event EnterDelegate EnterDelegateEvent;
public event ExitDelegate ExitDelegateEvent;
public Enter(EventEventArgs e)
{
// do something
EnterOrder(e);
ExitEventArgs ev = new ExitEventArgs(string ticker, double prices.. etc);
ExitEvent(ev);
// update order status etc.
}
private double EnterOrder()
{
double ent = 0.00
if (EnterDelegateEvent != null)
{
ent = EnterDelegateEvent(this, e);
return ent;
}
else { return e.lo; }
}
public double ExitEvent(ExitEventArgs e)
{
// do something
ExitEvent(ev);
}
private double ExitEvent()
{
double ext = 0.00
if (ExitDelegateEvent != null)
{
ext = ExitDelegateEvent(this, e);
return ext;
}
else { return e.Hi; }
}
} // end Enter Class
Class EventHandlers
{
public double SendEnter(EventArgs e)
{
// send enter to order server here
return price;
}
public double SendExit(EventArgs e)
{
// send exit to order server here
return price
}
}
Orders Class
{
Enter ent = new Enter();
public GetOrders()
{
// get order data
// create order event
EnterEventArgs ev = new EnterEventArgs(ticker, price, data...etc);
ent.Enter(ev);
}
}
Orders.aspx.cs
{
EventHandlers evt = new EventHandlers();
Enter ent = new Enter();
Orders ord = new Orders();
Private void login()
{
// log into Orders Server
ent.EnterDelegateEvent += EnterDelegate(evt.SendEnter);
ent.ExitDelegateEvent += ExitDelegate(evt.SendExit);
}
private void logout()
{
// delete / remove delegate event handlers;
}
// initiate orders example event
private void btnclick_GetOrders()
{
ord.GetOrders();
}
}
In addition to running GetOrders, above, I also need to run another set of orders from GetBackTest().. This needs to be simultaneous at times so when it runs the EnterOrder() routine the EventDelegate needs to return if (EventDelegate == null) { return e.prices; }
Instead of using the EventHandler method...
Class Backtest
{
Enter ent = new Enter();
// kickoff enter order just as Orders Class does
// this class needs to NOT use the Event Delegate as Orders class does
}
Is there a straightforward way to turn the DelegateEvents on and off and make sure that only one of them is instantiated ?? IF I turn the Delegate events as Static, the the backtest class will use the eventhandler methods.

I'm not sure I completely understand the scenario you're describing, but events and delegates can be a little tricky at first. I would suggest reading up on some .NET event tutorials:
Events - http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx
Delegates - http://msdn.microsoft.com/en-us/library/aa288459(VS.71).aspx
Another tutorial - http://www.csharp-station.com/Tutorials/lesson14.aspx

I would suggest working out a flow diagram first. It seems to me what exactly you want to do is not clear. Maybe with a flow diagram (or some other way of documenting what the system does) it would be.
I'm not even sure you need delegates for this problem the way you describe it.

I really didn't have to use event delegate however using other parameters to routes events required adding them and using them throughout or using existing and causing havoc, so to route the trade events using event delegates, I just added:
EventDelegateName += new DelegateName(eventhandler); // to top of orders.cs
EventDelegateName -= new DelegateName(eventhandler); // to bottom of orders.cs
so when backtest.cs ran the (Event == null) ran the alternate method.

Related

Unregister Events MultiCastDelegate Performance Problem

I have a problem: Our application has grown so far and therefore there is an object with many many EventHandlers. The point here is that removing them takes far more time, than adding them. This can be tested very fast:
Create a class with a
public event EventHandler
Make a second time and register to the event in first class like 300'000 times.
Here comes the interesting point: Registring needs like 0.1 seconds, whereas deregistring needs 5 minutes and it's growing almost exponentially.
Does anyone have a solution for that? The only one I found is to solve it over a WeakEventHandler (with it's downsides), but maybe there is another possiblity.
Example:
public class ClassWithValueChangedEvent
{
public event EventHandler ValueChanged;
public ClassWithValueChangedEvent()
{
}
}
public class MainWindowViewModel
{
public MainWindowViewModel()
{
DateTime start = DateTime.Now;
var classInstance = new ClassWithValueChangedEvent();
for (int i = 0; i < 300000; i++)
{
classInstance.ValueChanged += ClassWithValueChangedOnValueChanged;
}
Debug.WriteLine($"Elapsed Time: {(DateTime.Now - start).TotalSeconds}");
start = DateTime.Now;
for (int i = 0; i < 300000; i++)
{
classInstance.ValueChanged -= ClassWithValueChangedOnValueChanged;
}
Debug.WriteLine($"Elapsed Time: {(DateTime.Now - start).TotalSeconds}");
If we need to remove all event handlers
What I would do is that I would create an Unset method inside the class that nullifies the ValueChanged event handler like bellow:
public class ClassWithValueChangedEvent
{
public event EventHandler ValueChanged;
public void Unset()
{
ValueChanged = null;
}
}
Then, when needed I would do:
classInstance.Unset();
This is almost instantaneous.
If we need to remove individual event handlers
The process bellow is much more complicated and I don't know if I would choose it if I was in such need. The idea is that we create a custom list and we invoke the handlers manually:
public class ClassWithValueChangedEvent
{
private List<EventHandler> eventHandlers = new List<EventHandler>();
public void SetEventHandler(EventHandler evt)
{
eventHandlers.Add(evt);
}
public void UnsetEventHandler(EventHandler evt)
{
eventHandlers.Remove(evt);
}
public void UnsetAll()
{
eventHandlers.Clear();
}
public void CallEventHandlers(object? sender, EventArgs e)
{
eventHandlers.All(p => { p(sender, e); return true; });
}
}
Then, the methods of this class can be called as:
classInstance.SetEventHandler(ClassWithValueChangedOnValueChanged);
classInstance.CallEventHandlers(null, null);
classInstance.UnsetEventHandler(ClassWithValueChangedOnValueChanged);
Removing 300000 event handlers takes around 9 seconds which is much faster than minutes. I guess also that there must be a much faster way to do something like that.
I solved this question in using the WeakEventManager<>.AddHandler() from microsoft, which does not immediately remove the event handlers. It did not matter in this case.

Progress Bar in DLL

I am creating DLL which contains loop of some data
how can i display progress bar
I tried to create new windows Form and displayed the same in for loop
but it ask me to close the form every time
People on SO are not here to write code for you - they are here to solve problems. Anyway, I am going to show you how you could do it, and then you can write your code based on what I provide.
First of all, a "DLL" is a Dynamic-link library. Therefore, you can attach it to any project you have (winform or unity 3d game and no, you will not do it but let's just say it could be used in both cases) so if you are already writing DLL's, make it usable in a lot of scenarios and provide the programmer with a lot possibilities for manipulation.
So, your task is divided in 2 parts here:
Calculate data
Inform the user of what stage of the calculation they are at now
For this task, we will use events and a simple for loop to show you how it works.
First of all, let's create an EventArgs class that will store all the data we want to pass when the programmer from the other code catches the event:
public class CustomEventArgs
{
public int OldResult { get; set; }
public int NewResult { get; set; }
}
Now, when we have an event class let's implement it in our code.
public class YourDllCalculation
{
// In the .NET Framework class library, events are based on the EventHandler delegate and the EventArgs base class.
// So we create delegate using our newly created class to represents it like EventHandler
public delegate void ResultChangeEventHandler(object sender, CustomEventArgs e);
// Now we create our event
public event IzborRobeEventHandler ResultChanged;
// Local storing variable
private int Result = 0;
// This is method from which you inform event something changed and user listening to event catch EventArgs passed (in our case our CustomEventArgs)
protected virtual void OnResultChange(CustomEventArgs e)
{
ResultChangeEventHandler h = ResultChanged;
if (h != null)
h(this, e);
}
// We will use this method from new code to start calculation;
public void StartCalculation()
{
// Calculation will be done in separate thread so your code could proceed further if needed
Thread t1 = new Thread(Calculate);
t1.Start();
}
private void Calculate()
{
for(int i = 0; i < 100; i++)
{
OnResultChange(new CustomEventArgs() { OldResult = i, NewResult = i + 1 });
Result = i;
Thread.Sleep(1000); // Pause thread from running for 1 sec
}
}
}
Now that we have our code we can use it like this in our Winform:
// Add at top
using YourDllNamespace;
public YourForm()
{
// Creating our class for calculation
YourDllCalculation calc = new YourDllCalculation();
calc += CalculationResultChanged;
calc.Calculate();
}
private void CalculationResultChanged(object sender, CustomEventArgs e)
{
// Here do whatever you want with passed values
// e.OldResult;
// e.NewResult;
// it will fire each second
}

C# delegate v.s. EventHandler

I want to send an alert message to any subscribers when a trap occurred.
The code I created works fine using a delegate method myDelegate del.
My questions are:
I want to know whether it's better to use EventHandler instead of a delegate?
I'm not sure what the differences are between a delegate and an EventHandler in my case.
notify(trapinfo t), that's what I've done here to get trap information. But it seems not to be a good idea. I read some online tutorial lesson introducing passing delegate object; I'm wondering if it's appropriate in my case? And how should I do it? Any suggestions?
Thanks a lot :)
My code:
public class trapinfo
{
public string info;
public string ip;
public string cause;
}
public class trap
{
public delegate void myDelegate(trapinfo t);
public myDelegate del;
trapinfo info = new trapinfo();
public void run()
{
//While(true)
// If a trap occurred, notify the subscriber
for (; ; )
{
Thread.Sleep(500);
foreach (myDelegate d in del.GetInvocationList())
{
info.cause = "Shut Down";
info.ip = "192.168.0.1";
info.info = "Test";
d.Invoke(info);
}
}
}
}
public class machine
{
private int _occuredtime=0;
public trapinfo info = new trapinfo();
public void notify(trapinfo t)
{
++_occuredtime;
info.cause = t.cause;
info.info = t.info;
info.ip = t.ip;
getInfo();
}
public void subscribe(trap t)
{
t.del += new trap.myDelegate(notify);
}
public void getInfo()
{
Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
info.cause, info.info, info.ip,_occuredtime);
}
}
class Program
{
static void Main(string[] args)
{
trap t = new trap();
machine machineA = new machine();
machineA.subscribe(t);
t.run();
}
}
Update 2013-08-12
How about the observer/observable design pattern, that looks great in my case (EventHandler).
In my case, a machine subscribes to a trap messenger. (Add a machine to an invocation list)
Once a trap occurred, I send a message to all machines which are subscribed. (Call HandleEvent to handle it)
Advantages:
don't care about GetInvocationList() anymore, just use (+=) and (-=) to decide whom to send the trap.
It's easier to understand the logic of my program.
I know there are several ways to do it, but I wish I could analyze its pros and cons.
And thanks for your comments and suggestions, that would be very helpful!
I read the MSDN EventArgs article which Matthew Watson suggested.
Here's my Event Version:
public class TrapInfoEventArgs : EventArgs
{
public int info { get; set; }
public string ip { get; set; }
public string cause { get; set; }
}
public class trap
{
public event EventHandler<TrapInfoEventArgs> TrapOccurred;
protected virtual void OnTrapOccurred(TrapInfoEventArgs e)
{
EventHandler<TrapInfoEventArgs> handler = TrapOccurred;
if (handler != null)
{
handler(this, e);
}
}
public void run()
{
//While(true)
// If a trap occurred, notify the subscriber
for (; ; )
{
Thread.Sleep(500);
TrapInfoEventArgs args = new TrapInfoEventArgs();
args.cause = "Shut Down";
OnTrapOccurred(args);
}
}
}
public class machine
{
public void c_TrapOccurred(object sender, TrapInfoEventArgs e)
{
Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
e.cause, e.info, e.ip, DateTime.Now.ToString());
}
}
class Program
{
static void Main(string[] args)
{
trap t = new trap();
machine machineA = new machine();
t.TrapOccurred += machineA.c_TrapOccurred; //notify machine A
t.run();
}
}
The difference between event and delegate is that:
event declaration adds a layer of protection on the delegate instance.
This protection prevents clients of the delegate from resetting the
delegate and its invocation list, and only allows adding or removing
targets from the invocation list
See What are the differences between delegates and events?
2) As I see it, your subscriber should not change delegates freely. One subscriber can assign = to it instead of adding +=. This will assign a new delegate, therefore, the previous delegate with its invocation list will be lost and previous subscribers will not be called anymore. So you should use Event for sure. Or you can change your code to make your delegate private and write additional functions for manipulating it to define your own event behavior.
//preventing direct assignment
private myDelegate del ;
public void AddCallback(myDelegate m){
del += m;
}
public void RemoveCallback(myDelegate m){
del -= m;
}
//or
public static trap operator +(trap x,myDelegate m){
x.AddCallback(m);
return x;
}
public static trap operator -(trap x, myDelegate m)
{
x.RemoveCallback(m);
return x;
}
//usage
//t.AddCallback(new trap.myDelegate(notify));
t+=new trap.myDelegate(notify);
It is much better to use an event for your example.
An event is understood by the Visual Studio Form and WPF designers, so you can use the IDE to subscribe to events.
When raising events, there is no need for you to write your own foreach handling to iterate through them.
events are the way that most programmers will expect this functionality to be accessed.
If you use a delegate, the consuming code can mess around with it in ways that you will want to prevent (such as resetting its invocation list). events do not allow that to happen.
As for your second question: Using an event you would create a class derived from EventArgs to hold the data, and pass that to the event when you raise it. The consumer will then have access to it.
See here for details: http://msdn.microsoft.com/en-us/library/system.eventargs.aspx

How do I use Dynamic Fifo in C#? [duplicate]

I need to be able to trigger a event whenever an object is added to a Queue<Delegate>.
I created a new class that extends Queue:
public delegate void ChangedEventHandler(object sender, EventArgs e);
public class QueueWithChange<Delegate> : Queue<Delegate>
{
public event ChangedEventHandler Changed;
protected virtual void OnChanged(EventArgs e) {
if (Changed != null)
{
Changed(this, e);
}
}
}
And then attached the event from another class, like such:
QueueWithChange<TimerDelegate> eventQueue = new QueueWithChange<TimerDelegate>();
//
eventQueue.Changed += new ChangedEventHandler(delegate(object s, EventArgs ex) {
//This event is not being triggered, so this code is unreachable atm...and that is my problem
if (eventQueue.Count > 0)
{
eventQueue.Dequeue().Invoke(new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(5) });
actionTimer.Stop();
}
});
But whenever I enqueue an object (eventQueue.Enqueue(something)), the attached event is not being fired.
What am I missing here?
If you mean the non-generic Queue class, then you can just override Enqueue:
public override void Enqueue(object obj)
{
base.Enqueue(obj);
OnChanged(EventArgs.Empty);
}
However, if you mean the generic Queue<T> class, then note that there is no suitable virtual method to override. You might do better to encapsulate the queue with your own class:
(** important edit: removed base-class!!! **)
class Foo<T>
{
private readonly Queue<T> queue = new Queue<T>();
public event EventHandler Changed;
protected virtual void OnChanged()
{
if (Changed != null) Changed(this, EventArgs.Empty);
}
public virtual void Enqueue(T item)
{
queue.Enqueue(item);
OnChanged();
}
public int Count { get { return queue.Count; } }
public virtual T Dequeue()
{
T item = queue.Dequeue();
OnChanged();
return item;
}
}
However, looking at your code, it seems possible that you are using multiple threads here. If that is the case, consider a threaded queue instead.
I just did write up on what I call a TriggeredQueue. It's inspired the answer by Marc Gravell.
You can find my post here: http://joesauve.com/triggeredqueuet
And the Gist here: http://gist.github.com/jsauve/b2e8496172fdabd370c4
It has four events:
WillEnqueue
WillDequeue
DidEnqueue
DidDequeue
You can hook into any of these like so:
YourQueue.WillEnqueue += (sender, e) => {
// kick off some process
};
YourQueue.DidEnqueue += (sender, e) => {
// kick off some process
// e.Item provides access to the enqueued item, if you like
};
YourQueue.WillDequeue += (sender, e) => {
// kick off some process
};
YourQueue.DidDequeue += (sender, e) => {
// kick off some process
// e.Item provides access to the dequeued item, if you like
};
One neat trick is that you can use the DidDequeue method to kick off some process to ensure that the queue is full by making a web request or loading some data from a filesystem, etc. I use this class in Xamarin mobile apps to ensure that data and images are pre-cached in order to provide a smooth user experience, instead of loading images AFTER they scroll onto the screen (like you might see in Facebook and countless other apps).
try
public new void Enqueue(Delegate d)
{
base.Enqueue(d);
OnChanged(EventArgs.Empty);
}
You have to override Enqueue, to call OnChanged.

One shot events using Lambda in C#

I find myself doing this sort of thing quite often:-
EventHandler eh = null; //can't assign lambda directly since it uses eh
eh = (s, args) =>
{
//small snippet of code here
((SomeType)s).SomeEvent -= eh;
}
variableOfSomeType.SomeEvent += eh;
Basically I only want to attach an event handler to listen for one shot from the event, I no longer want to stay attached after that. Quite often that "snippert of code" is just one line.
My mind is going a bit numb, I'm sure there must be something I can do so I don't need to repeat all this overhead. Bear in mind that EventHandler may well be EventHandler<T>.
Any ideas how I can tidy up the repeative part of the code and just leave the snippet in a Lambda?
You could attache a permanent event handler to the event. The event handler then invokes "one shot event handlers" that are added to an internal queue:
OneShotHandlerQueue<EventArgs> queue = new OneShotHandlerQueue<EventArgs>();
Test test = new Test();
// attach permanent event handler
test.Done += queue.Handle;
// add a "one shot" event handler
queue.Add((sender, e) => Console.WriteLine(e));
test.Start();
// add another "one shot" event handler
queue.Add((sender, e) => Console.WriteLine(e));
test.Start();
Code:
class OneShotHandlerQueue<TEventArgs> where TEventArgs : EventArgs {
private ConcurrentQueue<EventHandler<TEventArgs>> queue;
public OneShotHandlerQueue() {
this.queue = new ConcurrentQueue<EventHandler<TEventArgs>>();
}
public void Handle(object sender, TEventArgs e) {
EventHandler<TEventArgs> handler;
if (this.queue.TryDequeue(out handler) && (handler != null))
handler(sender, e);
}
public void Add(EventHandler<TEventArgs> handler) {
this.queue.Enqueue(handler);
}
}
Test class:
class Test {
public event EventHandler Done;
public void Start() {
this.OnDone(new EventArgs());
}
protected virtual void OnDone(EventArgs e) {
EventHandler handler = this.Done;
if (handler != null)
handler(this, e);
}
}
You can use reflection:
public static class Listener {
public static void ListenOnce(this object eventSource, string eventName, EventHandler handler) {
var eventInfo = eventSource.GetType().GetEvent(eventName);
EventHandler internalHandler = null;
internalHandler = (src, args) => {
eventInfo.RemoveEventHandler(eventSource, internalHandler);
handler(src, args);
};
eventInfo.AddEventHandler(eventSource, internalHandler);
}
public static void ListenOnce<TEventArgs>(this object eventSource, string eventName, EventHandler<TEventArgs> handler) where TEventArgs : EventArgs {
var eventInfo = eventSource.GetType().GetEvent(eventName);
EventHandler<TEventArgs> internalHandler = null;
internalHandler = (src, args) => {
eventInfo.RemoveEventHandler(eventSource, internalHandler);
handler(src, args);
};
eventInfo.AddEventHandler(eventSource, internalHandler);
}
}
Use it like so:
variableOfSomeType.ListenOnce("SomeEvent",
(s, args) => Console.WriteLine("I should print only once!"));
variableOfSomeType.ListenOnce<InterestingEventArgs>("SomeOtherEvent",
(s, args) => Console.WriteLine("I should print only once!"));
If you can use the Reactive Extensions for .NET, you can simplify this.
You can make an Observable from an event, and only listen for the first element using .Take(1), to do your small snippet of code. This turns this entire process into a couple of lines of code.
Edit: In order to demonstrate, I've made a full sample program (I'll paste below).
I moved the observable creation and subscription into a method (HandleOneShot). This lets you do what you're attempting with a single method call. For demonstrating, I made a class with two properties that implements INotifyPropertyChanged, and am listening for the first property changed event, writing to the console when it occurs.
This takes your code, and changes it to:
HandleOneShot<SomeEventArgs>(variableOfSomeType, "SomeEvent", e => {
// Small snippet of code here
});
Notice that all of the subscription/unsubscription happens automatically for you behind the scenes. There's no need to handle putting in the subscription manually - just Subscribe to the Observable, and Rx takes care of this for you.
When run, this code prints:
Setup...
Setting first property...
**** Prop2 Changed! /new val
Setting second property...
Setting first property again.
Press ENTER to continue...
You only get a single, one shot trigger of your event.
namespace ConsoleApplication1
{
using System;
using System.ComponentModel;
using System.Linq;
class Test : INotifyPropertyChanged
{
private string prop2;
private string prop;
public string Prop
{
get {
return prop;
}
set
{
if (prop != value)
{
prop = value;
if (PropertyChanged!=null)
PropertyChanged(this, new PropertyChangedEventArgs("Prop"));
}
}
}
public string Prop2
{
get
{
return prop2;
}
set
{
if (prop2 != value)
{
prop2 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Prop2"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
class Program
{
static void HandleOneShot<TEventArgs>(object target, string eventName, Action<TEventArgs> action) where TEventArgs : EventArgs
{
var obsEvent = Observable.FromEvent<TEventArgs>(target, eventName).Take(1);
obsEvent.Subscribe(a => action(a.EventArgs));
}
static void Main(string[] args)
{
Test test = new Test();
Console.WriteLine("Setup...");
HandleOneShot<PropertyChangedEventArgs>(
test,
"PropertyChanged",
e =>
{
Console.WriteLine(" **** {0} Changed! {1}/{2}!", e.PropertyName, test.Prop, test.Prop2);
});
Console.WriteLine("Setting first property...");
test.Prop2 = "new value";
Console.WriteLine("Setting second property...");
test.Prop = "second value";
Console.WriteLine("Setting first property again...");
test.Prop2 = "other value";
Console.WriteLine("Press ENTER to continue...");
Console.ReadLine();
}
}
}
Another user encountered a very similar problem, and I believe the solution in that thread applies here.
In particular, what you have is not an instance of the publish/subscribe pattern, its a message queue. Its easy enough to create your own message queue using a Queue{EventHandler}, where you dequeue events as you invoke them.
So instead of hooking on to an event handler, your "one-shot" events should expose a method allowing clients to add an function to the message queue.
Does it work? If so, then I say go for it. For a one-shot event that looks to be quite elegant.
What I like...
If s is garbage collected, so will the event handler.
The detaching code is right next to the attaching code, making it easy to see what you are are doing.
You might be able to generalize it, but I'm not entierly sure how to because I can't seem to get a pointer to a event.
Personally, I just create a specialized extension method for whatever type has the event I'm dealing with.
Here's a basic version of something I am using right now:
namespace MyLibrary
{
public static class FrameworkElementExtensions
{
public static void HandleWhenLoaded(this FrameworkElement el, RoutedEventHandler handler)
{
RoutedEventHandler wrapperHandler = null;
wrapperHandler = delegate
{
el.Loaded -= wrapperHandler;
handler(el, null);
};
el.Loaded += wrapperHandler;
}
}
}
The reason I think this is the best solution is because you often don't need to just handle the event one time. You also often need to check if the event has already passed... For instance, here is another version of the above extension method that uses an attached property to check if the element is already loaded, in which case it just calls the given handler right away:
namespace MyLibraryOrApplication
{
public static class FrameworkElementExtensions
{
public static void HandleWhenLoaded(this FrameworkElement el, RoutedEventHandler handler)
{
if ((bool)el.GetValue(View.IsLoadedProperty))
{
// el already loaded, call the handler now.
handler(el, null);
return;
}
// el not loaded yet. Attach a wrapper handler that can be removed upon execution.
RoutedEventHandler wrapperHandler = null;
wrapperHandler = delegate
{
el.Loaded -= wrapperHandler;
el.SetValue(View.IsLoadedProperty, true);
handler(el, null);
};
el.Loaded += wrapperHandler;
}
}
}
You probably want to work with the new async/await idioms.
Usually when I need to execute an event handler one-shot like you described, what I really need is something like:
await variableOfSomeSort.SomeMethodAsync();
//small snippet of code here
Why not do use the delegate stack built into the event?
Something like...
private void OnCheckedIn(object sender, Session e)
{
EventHandler<Session> nextInLine = null;
lock (_syncLock)
{
if (SessionCheckedIn != null)
{
nextInLine = (EventHandler<Session>)SessionCheckedIn.GetInvocationList()[0];
SessionCheckedIn -= nextInLine;
}
}
if ( nextInLine != null )
{
nextInLine(this, e);
}
}

Categories