J'utilise un objet NativeWindow
pour sous-classer une pompe de message d'une fenêtre non gérée, dans le but d'intercepter ses messages.C#: Qu'est-ce qui détruit mon objet NativeWindow et pourquoi?
ressemble à ceci (son psuedo C#, s'il vous plaît excuser des problèmes mineurs de syntaxe):
class AppSubclass : Control {
class SpecialAppWndProc : NativeWindow {
protected override void WndProc(ref Message m) {
switch (m.msg) {
// do stuff
if (SpecialEvent != null) SpecialEvent(x);
}
base.WndProc(ref m);
}
public delegate void SpecialEventHandler(int Xstart);
public event SpecialEventHandler SpecialEvent;
~SpecialAppWndProc() {
DebugTrace("Help! Save me!");
}
}
private SpecialAppWndProc specialAppWndProc = new SpecialAppWndProc();
private void StartMonitoring() {
// do stuff
specialAppWndProc.AssignHandle(hWndUnmanagedWindow);
specialAppWndProc.SpecialEvent += new SpecialAppWndProc.SpecialEventHandler(specialAppWndProc_SpecialEvent);
}
/* ... event handler ... */
public AppSubClass() {
StartMonitoring();
}
}
Maintenant, je pensais que la fixation d'un écouteur d'événement serait suffisante pour maintenir le Garbage Collector à la baie, si mon objet est en train de mourir à cause du GC. Si ce n'est pas le cas, est-il possible de tracer comment et pourquoi? Je n'ai jamais connu .Net pour tuer des objets en raison de bogues de code (les exceptions et l'échec silencieux occasionnel semblent être l'essentiel) et je ne sais pas comment ou pourquoi l'application hôte (mon application est un serveur COM pour code non géré) aurait assez de connaissances pour tuer mes objets non plus.
Étant donné que l'objet meurt apparemment au hasard (je ne l'ai pas été en mesure d'identifier un certain ensemble d'événements, seulement qu'il meurt partout de moins d'une seconde à quelques minutes après StartMonitoring() est appelée.
Il semblerait que HandleRef
pourrait résoudre mes problèmes, mais je ne comprends pas comment utiliser cela dans ce contexte et je ne peux pas penser à comment l'insérer dans mon code (à part peut-être en déclarer un au niveau AppSubclass puis en assignant Alors, comment puis-je empêcher mon objet de mourir avant que je ne sois prêt à mourir?
Je ne suis pas entièrement sûr de comprendre votre réponse , cependant, j'ai pris l'habitude de créer un élément 'HandleRef' dans' AppSubclass' puis de le construire 'StartMonitoring()' et le problème semble s'être dissipé. Je vous remercie! –
Un événement est essentiellement un délégué et consiste en une référence à la méthode que vous lui avez assignée et à l'objet sur lequel la méthode sera déclenchée. Prenez ceci: bt.Click + = bt_click; L'événement click fera maintenant référence à bt_Click sur "this", cependant, ce code n'ajoute aucune référence supplémentaire à l'objet référencé par bt, donc si la variable bt est modifiée plus tard (ou sort de la portée) et que c'était le seule référence à cet objet, cet objet est désormais éligible pour la collecte. –
@Tom: Vous devez prendre le temps de comprendre la réponse de Lasse; ** Si vous ne maintenez pas de référence à votre objet quelque part dans votre code, votre objet peut être collecté **. Cela ne veut pas dire que ça le sera, mais ça PEUT l'être. –