How to subscribe an EventHandler? [Answered]
I don't understand how to subscribe this. I don't get it. I honestly don't even know why I used an
EventHandler
instead of an Action or something.
230 Replies
actually at this point I'm sure I'm doing the exercise wrong.
tree.Ripened += OnRipened;
you dont want to invoke the method, you want the method itselfyeah that's right. I just changed the EventHandler to an Action? also
also
Notifier
should be called NotificationHandler
, it doesnt notify anything
sureOh really okay
or preferably change the handler signature
Idk what that means lol
Okay yeah I could have done that.
the handler's signature has to match the event delegate's signature
yeah thanks. Give me one second to figure out next question.
which is
EventHandler<RipenedEventArgs>
Okay I remember reading that EventArgs is how data is passed
yeah thats one way to pass data
its the convention tho
and my interpretation was using that to pass the
Ripe
value of the tree
did I do that correctly?sure yeah
okay I'm changing back to EventHandler then lol
sec
maybe name it
IsRipe
to be clearerin the eventarg?
and the class
cause the top portion is part copied from example ye i dun wanna do that
lol
ah fair
This is the reference it gave
This is the instruction
and my first post is what I've done
i think the harvester is the one that should subscribe to the event
So my problem with the EventHandler thing is I don't sub the event through the ctor like instructed
wdym
the instruction suggest taking the tree through the other classes constructor to sub the event in the
CharberryTree
classyeah whats the problem with that
I'd have to set a property / field to hold the what the constructor paramter takes in, and then reference that in the class taking the EventArg?
I'm just not sure how it works lol. The EventArg example didn't have any stuff poppin' in a constructors parameters.
well you only need to subscribe to the event
which you already did
so all thats left for this class is to print a message to the console saying the tree has ripened
anyway gtg its 2 am
goodluck
ty lol gn homie
well I gott ajet anyways. I guess I'll finish this later too. xD. Thanks again homie.
My event in
Notifier
is not being called. it's getting to my Ripened?.Invoke()
line and going back to the while loop at start
I'm noticing my EventHandler<RipenedEventArgs> ?Ripened;
is null when invoked and I'm not sure why that is either.You never subscribe anything to
tree.Ripened
If I understand correctly
tree.Ripened += OnRipened;
in the public Notifier(CharberryTree tree)
subscribes the event? Sorry I forgot to update codeand what part of your code calls the
Notifier
constructor?I thought the
MaybeGrow()
method did with Ripened.Invoke()
no, none of that code contains a call to any constructor
Oh I never made a
Notifier
or Harvester
so I can't use them
lol tyvm.
Hey so quick question about what was happenigbefore I created the new objects this was always null
I don't understand.
.
so the event being null is having nothing subscribed
okay
that's the first time I've ran into anything that was null because of a relationship to something else iirc
so I have another question I guess
well one moment let me collect mythoughts
so the goal of the exercise is to have the tree ripen, notify, and havest (
Ripe = false
again)
how to order events?Ero#1111
REPL Result: Success
Console Output
Compile: 780.351ms | Execution: 89.895ms | React with ❌ to remove this embed.
i'm not super familiar with event patterns unfortunately
I'll be hoenst that shoots entirely over my head
no problem. could you explain the thing?
what thing?
i assume
foo.Bar += (s, e) => { };
is what confuses you?yes
just a very shorthand form of subscribing
I don't get the output lol so maybe the whole thing confuses
xD
oh i was just showing whether
foo.Bar
was null or not
showing that it is null before subscribing anything, and not null afteroh okay
OH you were showing the error I had
okay yeah tyvm. That was a new experience, where the relation itself is the content checked
yeah that is illuminating. could you explain the shorthand? what is s, e?
like i'd personally just have
Action
s for this, i rarely use delegates or events
sender
and whatever type the EventHandler takes (in my case, string
)I used
EventHandler
because it seemed like the easiest way to share the Ripe
property in the eventi just woulnd't even share it
like why would another class care about my tree growing and ripening
well my goal was just to play with it because I'd never used it.
well Harvester *will set *
Ripe
back to false
so I was going to try to use the event data to determine that
So just wanted to explore the functions I guess
Why do you like Actions?
Oh yeah I forgot EventHandler
has two parameters!e
whoops, probability too small
It does seem easier overall to use lol
but maybe there are some patterns i don't know about
shrug idk either lol. I just know from example reference
EventHandler
was made to pass data around for you so I wanted to give it a go. I'll ask for criticism once complete in a minute or two.Re event vs action, there are a few tradeoffs
events can have multiple listeners, for one
So I'll be honest I'm confused why in the
public class Harvester
method OnRipened
using Tree.Ripe = false;
sets the tree
object bool of Ripe
back to false
sorry for interrupting Pobieganp
and events sort of represent a less tightly coupled integration, imho
okay
1 listener on Action sounds weird, why is that?
wdym? thats just how it is
lol okay idk
`
cs
this code that Ero posted for example
once you set the OnRipen
action, how would someone else add their listener to it?
they can't. they'd replace the current one
events support the += MyHandler
tjhing out of the boxI didn't try the multidelegate(probably wrong word) or chaining thing that was talked of in book
is that event specific?
Action
is a delegate typeOH okay
nah you're correct
events are supported by a multi delegate
okay thanks for that.
why
event
vs eventhandler
then?hm?
well an event is an event
honestly that part is a bit confusing
Handling and Raising Events
Learn to handle and raise .NET events, which are based on the delegate model. This model lets subscribers register with or receive notifications from providers.
EventHandler is a type, much like
Counter
or string
etc
so to make an event, you say event MyEventType MyEventName;
right right
the type declares what parameters a handler must have
Oh so it's a premade type of event
but since its all delegates in the background, you can assign any method to be your "handler"
yeah okay
EventHandler
is a premade delegate type, yesdude this is wild lol
mhm
it can be confusing
but ITS ALL DELEGATES
😄
I know lmaooooo
the book made sure to emphasize over and over that it was uh, delegates underneath
essentially, use
event
for actual events, like OnRipened
etcmade me think of inumerable under things
so like Linq
I tend to use
Action
like "events" when I do testing stubs
since I know I will never ever have more than one "listener/handler"okay yeah.
I'm finding things up until this point were super easy
but things like this are like, multi step processes you put on top of all the other stuff
idk haha.
I seem to recall you asking some questions before, so not "super easy" :p
I tried learning events a long time ago when I had a worse grasp of C#
LOL yeah I'm just saying it's like a new layer of abstract concept to slap on the top of things
haha yeah
it pretty much is
could you offer whatever basic criticism of what I wrote?
OOHHH I asked earlier about that
Tree.Ripe = false
toward the bottompublic event EventHandler<RipenedEventArgs> ?Ripened;
that questionmark really bothers me
its part of the type, not the nameOh okay I always forget where those go tbh lol
I thought it was for the variable specifically xD
well it is, but its part of the type
you are saying this variable is of type
EventHandler<RipenedEventArgs>?
so it can be null
so, this seems okay.
I'd perhaps change the Tree.Ripe = false
to be tree.Harvest()
or something
depends on how you wanna divvie up your responsibliitesyeah ofc that makes sense
should a tree know how to be harvested, or should a harvester know about trees?
OH BUT HEY that tree thing there
how does referencing the class property change the other classes property
hm?
wdym
Exactly that way
yeah exactly that way :p
Tree
in that case is of the Harvester
classIt's a reference
OH
its not a copy
its a reference to the actual thing
$refvsvalue
shoot I did not realize that
Classes are always passed byref
I think I need a cheat sheet to put that on lol
your "architecture" here is a bit unusual too
in that your notifier/harvester both hold a hard ref to the tree
instead of just registering their listeners and getting the tree that ripened from there
what if you had one harvester responsible for 10 trees?
the event args should contain the tree that ripened (its the sender in your case)
yeah yeah okay
so just the constructor param is enough?
well the Harvester uses the reference
Perhaps you'd want a static harvester class which acts as an extension on the tree
I don't understand that tbh
but I'm excited to be exposed to the idea
lol
Also I tried using the
sender
object to get the tree and couldn't figure it out
OH okay
sender is not a reference to itobviously, since you register your handler in the ctor, this isn't super useful
you'd probably move that out to a new method
no it is, but its being sent as
object
so you do a typecheckI said static extension for a reason
if sender is CharberryTree tree
yuphmm that's cool okay
can you give example of static here??
your harvester doesnt really need to be what it is
currently
oh?
yeah all it does is change something on the source and print a message to the console
Ok i can't code this on my phone gimme a bit
that could easily be a static method
an extension method to register it with would be neat
Oh well I'm just following exercise instruction which was to make it a class
yeah, thats fine
but I would love to know what you're talking about
yeah dude I'm here to learn lmao, this is fucking great
because most of the time, you'll want it to be a class
nice.
its just that because this example is so simple, and doesnt need any instance data...
I'm sure Ero will post the code once they write it up
Oh that's right lol. @Ero Take your time bud no rush. I really, really appreciate the instruction.
so sender just grabs the object for a typecheck, it does not serve as a reference to the object as the type it is?
Also, regardless of how helpful you are, you really need to watch your snark. You are way to snarky way to often.
so just to clarify, I can send bunches of
EventArgs
in params and set them, and they all get passed around with reference to the object they come from??
look at how you invoke the event
Ripened?.Invoke(this, new RipenedEventArgs(Ripe));
the first parameter this
is the sender
that gets exposed to any listener
as does the event args, but its the same eventargs being passed to all listeners, one by oneright. so I could put
new RipenedEventArgs(Ripe, Age, Season, ...)
in there?yeah your eventargs is just an object with a bunch of props on it
"here is the info related to the event"
so its use is to pass all that around without needing a direct reference to the object?
for decoupling?
for example, on an "OnClick" event it contains the mouse location, what button was pressed, etc
ye
well you need the object ref to register the listener/handler but that might have happened via some abstraction yeah
its a way to invert the dependency actually
instead of your tree knowing about the harvester, its your harvester that knows about the tree
at least initially
That's so cool.
'hey look over here. It's a
sender
with args
loldo you know what the garbage collector is btw?
oh yes I meant to ask how that'd work here
unsubscribing in practice
yeah. unsubbing is the hard part
events often lead to memory leaks, becuse if you dont unsub, the registered handler will keep the event source alive forever
only when all the handlers get collected would the ref count reach 0 and the event source be collected
yeah all of that is wooshing
I mean I vaguely get it lol
the super simplified version of the garbage collector is that it just looks at how many references there are to an object
can you show me in my code where it'd be practical given some additional circumstance if necessary?
if that number reaches 0, the object gets cleaned up
?
what exactly?
in my exercise, where would I unsub the events, and if not anywhere, what premise would provide a practical place?
uhm, well your tree grows forever in a
while(true)
yeah I know lol
so you dont have any leaks.
I'm just saying to further my practical understanding of the matter so it's less of a floaty abstraction
imagine if you had multiple trees, and each tree had a chance to die each time it was harvested
ya
upon death, you'd want to unsub any and all listeners
the common way to do this is to just assign
null
to the event
i think this requires .net 7 and preview lang though
yup, static abstracts
but its a nice example of how something like this could look in a "real" project
given that your event handlers are simple
generics + extension methods = superpowers
so on tree death I'd just
Ripened = null
and that'd fix it?for that case, yes
there is a reverse thou, which is when the publisher (event source) lives longer than the subscriber
if the subscriber upon death doesnt unsub itself
I was just about to ask that lol
and @Ero I'll ask about your thing in a moment. Tyvm
I'ma go to sleep
❤️ okay. I appreciate the help bud.
its only really a problem when the lifetimes of the subscriber and the publisher differ greatly
have a good night.
why would sub need to keep reference of event around if source is gone?
to use the data in the arg?
no its the publisher that knows about the subscribers
oh okay
Yeah the order of execution here isn't really sensical
once the source dies, the handler will not be invoked
A tree shouldn't have a harvester
because the source is dead
yeah i get that
A harvester should be assigned the task of harvesting a number of trees
this SO explains it fairly well
https://stackoverflow.com/questions/4526829/why-and-how-to-avoid-event-handler-memory-leaks
NICE. getting pinned
I'm looking at what Ero shared
I've only used generics a couple times. This is super cool.
What is being extended here though? Or were you just saying extensionmethods are based af? lol
Tree in TreeFarm
extension methods are just static methods that "pretend" to be part of something else
so intead of doing
TreeFarm.AddNotifier(tree, ...)
you can call tree.AddNotifier(...)
its the exact same thingOh yeah okay
they are very common in modern C#
yeah everything in there is new to me so it's more than a bit confusing xD
I guess they don't need to be extensions
Generics, Events, and ExtensionMethods are things I've only done a couple times
Could just be part of tree
I'm gonna copy it and step through it
well you don't need to worry about this right now
oh well okay
hahahaha
your example is a bit contrived, and very simple
ya
You probably can't copy it anyway
Oh 😭 lol
Unless you have a preview version of .net 7 downloaded and bs 2022 preview installed
vs
That's a no lol
Then you'll have to wait until November lol
So what you folks are telling me is I did an okay job with this exercise and to move onto the next one?
xD
I refrain from commenting 😛
👀
Eh, it works, right?
lollllllllll
It's not something you would ever design in a real app
Like, we don't know the exercise, only your code
and as said, its a contrived example that is too simple to be realistic
I don't think there was a task
alright given that description, yeah you did alright
NICE.
Yeah that's fine
I'd remove the
Tree
prop from the harvester/notifier
but other than that, 👍heck yes
If anything make it a private field, but if it's not used, remove it completely
ya it's not used now
I had confusion about
sender
before which is why I had it
probably still have confusion about sender but that's okay
lol
❤️ thanks again Ero and Pobiega. Maybbe someday your discord handles will be references in my resume.
xDwtf
:d
don't
And isn't that truly why we're here
thats not what a reference is, lol
*referenced
"Give three references of people you know who can attest the quality of your work" Uhhh.. @Pobiega#2671, uhhh...
yeah, nah
lmao
I know I know I kid.
references on CVs need to be actual people you've worked with.
I'm just saying you folks are a large part of what's going to get me through this.
❤️
Hey I'm as real as any other person thank you
LOL
I'm just a shared figment of both your imaginations
DUDE POBIEGA, I HAVE AN INTERESTING TWIST ON THAT THAT HAS IMPLICATIONS ABOUT THE NATURE OF BEING
sorry, i dig philosophy though
To Hegel, 'being' is the product of a social function, that is 'consciousness reflecting on consciousness'
the object, that is subject, become subject of the subject.
/close
?LOL
okay fine.
:d
I was about to send that lmfao
haha ty again.
✅ This post has been marked as answered!