奇怪的,添加了一个组件功能, MousePreview , 其中使用了 SetWindowsHookEx , 然后出现了问题:
这个问题很奇怪,是一个 delegate 引起的, 然后查阅了msdn,
如下:
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/68fdc3dc-8d77-48c4-875c-5312baa56aee/
其中说了问题的原因和解决的方法。
我先贴一下问题代码:
public class MousePreview
{
private Control m_Control;
public MousePreview(Control p_Control)
{
NM.SetWindowsHookEx(7, new NM.HOOKPROC(MyMouseProc), 0, NM.GetCurrentThreadId());//WH_MOUSE = 7
m_Control = p_Control;
}
NM.HOOKPROC hookProc;
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
public int MyMouseProc(int nCode, int wParam, int lParam)
{
}
}
问题出在这一行:
NM.SetWindowsHookEx(7, new NM.HOOKPROC(MyMouseProc), 0, NM.GetCurrentThreadId());//WH_MOUSE = 7
问题是:
new NM.HOOKPROC(MyMouseProc)
这条语句创建了delegate,
但是SetWindowsHookEx是一个Unmanaged Code。
同时在Managed Code中没有把这个delegate的reference 计入(加一) , 所以出了作用域后,一旦GC启动, 这个delegate就被杀了!
如果(非常有可能),此时UnmanagedCode调用这个delegate , 那么整个程序就会崩掉哦!
这个对话框就是告诉我们这个严重问题!
我要说Managed Debug Assistant 真牛啊!!!!这个问题给他在调试的时候找出来了!
解决的问题,太简单了,如下:
public MousePreview(Control p_Control)
{
NM.SetWindowsHookEx(7, hookProc = new NM.HOOKPROC(MyMouseProc), 0, NM.GetCurrentThreadId());//WH_MOUSE = 7
m_Control = p_Control;
}
NM.HOOKPROC hookProc;
只要在类中加上一个变量,使delegate和类同生同死就可以了。
p.s: 在这个类中,应当在 Dispose 中处理 UnHook!
或者析构函数