CallbackOnCollectedDelegate a été détecté
Je suis sous-classement d'une application. Mon sous-classé procédure de Fenêtre est dans une DLL. Mon code de sous-classement à l'intérieur de la DLL ressemble un peu à ce (démonté, enlevé d'autres non-parties liées).
class FooBar
{
private delegate int WndProcDelegateType(IntPtr hWnd, int uMsg,
int wParam, int lParam);
private const int GWL_WNDPROC = (-4);
private static IntPtr oldWndProc = IntPtr.Zero;
private static WndProcDelegateType newWndProc = new
WndProcDelegateType(MyWndProc);
internal static bool bHooked = false;
[DllImport("user32.dll")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex,
WndProcDelegateType dwNewLong);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex,
IntPtr dwNewLong);
[DllImport("user32")]
private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd,
int Msg, int wParam, int lParam);
private static int MyWndProc(IntPtr lhWnd, int Msg, int wParam, int lParam)
{
switch (Msg)
{
//the usual stuff
//finally
return CallWindowProc(oldWndProc, lhWnd, Msg, wParam, lParam);
}
internal static void Hook()
{
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc);
bHooked = oldWndProc != IntPtr.Zero;
}
internal static void Unhook()
{
if (bHooked) SetWindowLong(hWnd, GWL_WNDPROC, oldWndProc);
}
}
Maintenant, même si je suis titulaire d'une référence forte à la WndProc dans une classe de niveau statique de la variable d'instance du délégué, j'ai cette erreur.
CallbackOnCollectedDelegate a été détecté
Message: Un rappel a été fait sur un
les ordures collectées délégué de type
'PowerPointAddIn1!FooBar+WndProcDelegateType::Invoke'.
Cela peut provoquer des crashs de l'application,
la corruption et la perte de données. Lors du passage de
les délégués à du code non managé, ils doivent être conservés
vivant par l'application gérée jusqu'
c'est la garantie qu'ils ne seront jamais
être appelé.
Ce que je fais mal?
OriginalL'auteur Water Cooler v2 | 2011-01-31
Vous devez vous connecter pour publier un commentaire.
Que les forces de C# pour créer un délégué de l'objet à la volée. Il traduit le code:
qui est un problème, que le délégué de l'objet n'est pas référencé nulle part. La prochaine collecte de déchets va le détruire, en tirant le tapis sous le code non managé. Vous avez déjà fait la bonne chose dans votre code, vous avez juste oublié de l'utiliser. Correctif:
Découlant de votre propre classe NativeWindow et utilise ses AssignHandle() la méthode est la meilleure souricière btw. Appel ReleaseHandle() lorsque vous voyez le message WM_DESTROY.
Erm, que dois-je regarder?
Désolé, je n'ai pas vous. Ai-je oublié quelque chose d'inexpliqué?
Je vous recommande d'utiliser la classe NativeWindow.
Assurez-vous. Permettez-moi de donner que d'essayer. Merci.
OriginalL'auteur Hans Passant
Appelez-moi fou, mais en conservant une référence devrait résoudre ce problème:
Si c'était si simple, je ne serais pas Googler ce pendant des heures sur la fin...
OriginalL'auteur ChaosPandion
la fonction de rappel peut être invoquée après les retours d'appel, l'appelant géré doivent prendre des mesures pour s'assurer que le délégué reste non perçus jusqu'à ce que la fonction de rappel de finitions. Pour obtenir des informations détaillées sur la prévention de la collecte des ordures, voir Interop Marshaling avec Plate-forme de l'Invoquer.
http://msdn.microsoft.com/en-us/library/eaw10et3.aspx
OriginalL'auteur Elshan