förhindrar eventhanterare objekt från att garbagecollectas? Hej. >förhindrar eventhanterare objekt från att garbagecollectas? oke , helt sant ang hwnd. :) >men! , när blir de cirkulära referenserna upplösta då? oke , må så vara , känns ändå som att det är 'fel' om de enda referenser som håller objektet vid liv kan vara eventhanterare...stor tjock delegat bugg i .net?
gör följande:
1) skapa en ny winforms app
2) lägg till en usercontrol
3) i usercontrollens "parentchanged" event gör så att usercontrollen lyssnar på parent containerns "mousemove" event
4) i usercontrollens "dispose" / "finalize / destructor" lägg en "console.writeline ("blah")
5 i mainformen gör följande
form_load(...)
Usercontrol1 uc=new Usercontrol1();
this.controls.add(uc);
uc.visible=true;
uc=null;
this.controls.clear();
GC.Collect();
...
om man startar appen nu så kommer man se att finalize/dispose INTE körs
men om man går tillbax till usercontrollen och remmar ut koden där den kopplar sig på mousemove på parent containern och startar igen , så kommer man se att finalize / dispose körs..
detta kan ju simpelt lösas genom att anropa .dispose() på usercontrollen.
MEN!
enligt msdn så ska man BARA anropa .dispose om objektet håller unmanaged resources eller db kopplingar (som jag antar bakom kulisserna är unmanaged)
och man ska ALDRIG anropa dispose på objekt som inte håller någon unmanaged resouce direkt eller indirekt...
så , ska man eller ska man inte anropa .dispose på windowsforms kontroller om de nu bara innehåller helt vanlig .net kod?????
//RogerSv: stor tjock delegat bugg i .net?
>>enligt msdn så ska man BARA anropa .dispose om objektet håller unmanaged resources eller db kopplingar (som jag antar bakom kulisserna är unmanaged)
>>och man ska ALDRIG anropa dispose på objekt som inte håller någon unmanaged resouce direkt eller indirekt...
Intressant. Hur skall man veta det??
Jag kör _oftast_ enligt regeln: Finns .Dispose(), kör den.
//freddaSv: stor tjock delegat bugg i .net?
Nja. Det kanske snarare fördröjer det. Eftersom GCn kan hantera cirkulära referenser så kommer de att rensas upp när både hanteraren och den som tillhandahåller händelsen inte refereras nånon annanstans.
>detta kan ju simpelt lösas genom att anropa .dispose() på usercontrollen. MEN!
>enligt msdn så ska man BARA anropa .dispose om objektet håller unmanaged
>resources eller db kopplingar (som jag antar bakom kulisserna är unmanaged)
Alla UserControl objekt (i alla fall om vi snackar Winforms) backas ju av ett HWND, så du kan ju inte ha en winforms kontroll som inte har några "unmanaged" resurser.
MSSv: stor tjock delegat bugg i .net?
men! , när blir de cirkulära referenserna upplösta då?
de blir det ju bevisligen inte när man anropar GC.Collect();
//RogerSv: stor tjock delegat bugg i .net?
Om du har en kontroll som refererar till ett formulär, och vice versa, så rensas de väl upp vid första GCn efter att du inte längre har några ytterligare referenser till varken formuläret eller kontrollen.
MSSv: stor tjock delegat bugg i .net?
men men..
här kommer ett annat lattjo problem med eventhanterare och winforms timern..
skapa ett winforms projekt
lägg till en usercontrol
lägg en WINDOWSFORMS TIMER (inte den andra) på userkontrollen.
sätt timern till enabled och koppla en eventhanterare på timerns "tick" event
lägg en "console.writeline" i userkontrollens dispose & finalize
gör samma sak som i första exemplet:
form_load(...)
Usercontrol1 uc=new Usercontrol1();
this.controls.add(uc);
uc.visible=true;
uc=null;
this.controls.clear();
GC.Collect();
...
starta appen...
nu kan man se att dispose/finalize inte körs i userkontrollen , och detta är för att timerns eventhanterare håller en ref till kontrollen ..
så även om du kastar alla referenser till den container som håller userkontrollen så kommer userkontrollen fortfarande ligga och kleta i minnet...
enda sättet att få den att dö på är att stänga av timern , och det skulle man ju vilja göra i finalize , då man vet att det inte finns några referenser kvar , MEN eftersom timern förhindrar att finalize körs , så kan vi inte göra detta ...
så det blir lite av ett moment22 här...
i det första fallet , med mousemove hanteraren så är det som MS sa , detta lösesupp när inga refs finns till userkontrollen eller till dess kontainer...
men i detta fallet så kommer userkontrollen ligga och skräpa i minnet för evigt , eller iaf tills du avslutar din app...
någon frisk ide' varför det blir så?
//Roger