C# delegte 函数到 Unmanaged 时引发的问题
奇怪的,添加了一个组件功能, 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!
或者析构函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏