#Beans5715 memorythe code looks something

1 messages · Page 1 of 1 (latest)

dim rapids
#

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?

devout dock
#

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
dim rapids
#

Ok I see, that is very helpful thank you

#

And that remove call is done automatically right?

devout dock
#

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

dim rapids
#

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

devout dock
#

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

dim rapids
#

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

devout dock
#

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

dim rapids
#

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?

devout dock
#

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

dim rapids
#

oh whoops yea forgot to remove the ref, was originally passing it to the constructor as such my bad

devout dock
#

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

dim rapids
#

gotcha
kinda a tangent i guess, but does this mean any value types referenced like the bool are boxed?

devout dock
#

in c# and in this circumstance yes