wpf - C# Unsubscribe via IDisposable: Why Does it Work? -
other questions , answers advocate using idisposable
interface unsubscribe events object subscribes in constructor. i'm failing understand why dispose()
method gets called in first place.
consider code (verbatim) this example:
public class detailviewmodel : idisposable { public detailviewmodel(mydetailmodel detailmodel) { // retain detail model this.model = detailmodel; // handle changes model not coming viewmodel this.model.propertychanged += model_propertychanged; // potential leak? } public void dispose() { this.model.propertychanged -= model_propertychanged; } }
so supposing model referenced datacontext
of window, should have no references when window closed , garbage collected. event detailmodel.propertychanged
still hold reference delegate (which why we're unsubscribing in first place). , each delegate implemented compiler-generated class hold reference instance (the detailviewmodel
) in auto-generated _target
field.
so _target
not count reference detailviewmodel
?
i see 2 cases.
- it count, ,
detailviewmodel
lives long event it's subscribing does, ,dispose
won't benefit since won't called until after subscribed object gets garbage collected. - it doesn't count, ,
detailviewmodel
gets disposed of call event removal code. ok, no more space leak. if don't implementidisposable
, , event gets fired , tries call delegate, points deleted object, why doesn't program crash? clr swallow exception?
i've been coding c# month, if i'm fundamentally misunderstanding something, please let me know.
firstly object can't point deleted object. objects garbage collected when no other objects (considered live) referenced object.
as per ms docs...
https://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx?f=255&mspperror=-2147217396
... dispose should safe call @ time! regardless of when or how many times has been called.
generally dispose() called when call it. if know object not going used again , haven't used using statement , object implements dispose(), should call dispose.
you don't implement dispose unless object has un-managed resources or has members implement dispose(). in practice have found, if want code behave across platforms (not desktop, mono, windows phone, windows ce etc), it's idea decouple objects (i.e. set stuff null) in dispose, try , give garbage collector as possible collect objects.
unsubscribing events can important because don't want object processing events objects remain live. quite in case, both observer (the event consumer) , subject/observeee (the object exposing event) have equal life times , go out of scope @ same time.
usually gc can recognise graphs of disassociated objects , collect them group.
i'd recommend reading...
https://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
...which gives further guidence on implementing dispose.
Comments
Post a Comment