#Beans5715 memorythe code looks something
1 messages · Page 1 of 1 (latest)
Ok I thiiink that makes sense. I figured "closures" were the concept I was missing. Haven't taken the time to understand them, but to repeat back my understanding:
when you create an anonymous function that writes to a variable, it exists during for the lifetime of the variable it writes to. so if it writes to a variable in a function scope, it will be freed when the scope is exited?
imagine a delegate is just an instance of a class
with the delegate method defined in it
and fields for everything that appears in the closure
the fact that you have a boolean is a little confusing - imagine it's not a value type, it's a reference, no matter what
then it will be clear that, you're just dealing with instances of a class
there isn't anything special going on
same with events, it's obscuring that += and -= just adds instances of this class to a list
so to rewrite your example
var complete = new object();
var completeAction = new CompleteAction();
completeAction.complete = complete;
myClass.someEvent.privateList.Add(completeAction);
await ... // no impact
myClass.someEvent.privateList.Remove(completeAction);
// some event has now been invoked
Ok I see, that is very helpful thank you
And that remove call is done automatically right?
no that's what -= translates into
i took your code and translated it line by line
into what is realyl happening
because the += and -= syntax is confusing
if you don't mind, then what would the translation be for an anonymous method which cannot be removed? that's the bit I'm worried about
what do you mean cannot be removed
var complete = false;
var completeAction = delegate() { complete = true; };
myClass.someEvent += completeAction;
await Task.When(() => complete);
myClass.someEvent -= completeAction;
myClass.someEvent -= completeAction; is myClass.someEvent.privateList.Remove(completeAction);
Remove as in List<T>.Remove
if you do:
void Function()
{
someEvent += () => print("hello")
}
you're subscribing an anonymous method, but you have no reference to it with which to remove it
okay
now rewrite that as
void Function()
{
someEvent.PrivateList.Add(new PrintHello());
}
does this make sense?
the rules about delegates and functions and blah blah blah
it's just adding and removing instances of a class to a list in disguise
i'm trying to show you that the fact that it is a function or an event doesn't matter
they are not treated specially
i am showing you the real implementation
so if you know how garbage collecting lists work, you know how garbage collecting events work
because that's all an event is
it's a list
it's syntactic sugar around a List<T>
no reference to it with which to remove it
same as in my rewritten example.
you can add new instances of something to a list all the time
it should now be clear under what circumstances you need -= in order to effect garbage collection (it basically does not)
it would get collected anyway
most of the time, for common usages of events
i appreciate that, still trying to wrap my head around the implications so bear with me
if this is the code I write
void Function()
{
var complete = false;
myClass.someEvent += () => complete = true;
await Task.When(() => complete);
}
in this instance, the code run behind the would loosely be
void Function()
{
bool complete = false;
myClass.someEvent.Add(new CompleteAction(object complete));
await Task.When(() => complete);
}
class CompleteAction
{
object complete;
public CompleteAction(object complete)
{
this.complete = complete;
}
void Invoke()
{
complete = true;
}
}
So if the listener is just an object, it wouldn't get garbage collected until you leave the function scope in which its complete reference is defined? or does the listener instance and complete reference get held in memory until the class that owns the event is garbage collected?
don't write +=
translate it fully
the scopes don't matter
don't think of it that way
okay
and don't do ref complete because it's weird
bool is weird
it's a BooleanObject
it's a boxed bool
oh whoops yea forgot to remove the ref, was originally passing it to the constructor as such my bad
yeah
so that's what's going on
any questions you have about garbage collection
now you are not using any weird syntactic sugar
it should be clear that whether Invoke is ever called does not matter
so the "scope" of invoke doesn't matter
it has no impact on the lifetime of object complete
gotcha
kinda a tangent i guess, but does this mean any value types referenced like the bool are boxed?
in c# and in this circumstance yes