API 响应按键事件例子,阻止内存回收,垃圾回收

    class KeyHook
    {
        public KeyHook()
        {
           
        }
        //private TextBox textBox1;
   
        internal enum HookType //枚举,钩子的类型
        {

            //MsgFilter = -1,

            //JournalRecord = 0,

            //JournalPlayback = 1,

            Keyboard = 2,

            //GetMessage = 3,

            //CallWndProc = 4,

            //CBT = 5,

            //SysMsgFilter = 6,

            //Mouse = 7,

            //Hardware = 8,

            //Debug = 9,

            //Shell = 10,

            //ForegroundIdle = 11,

            //CallWndProcRet = 12,

            //KeyboardLL = 13,

            //MouseLL = 14,

        };

        IntPtr _nextHookPtr; //记录Hook编号


        [DllImport("kernel32.dll")]
        static extern int GetCurrentThreadId(); //取得当前线程编号的API

        [DllImport("User32.dll")]
        internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API


        [DllImport("User32.dll")]
        internal extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API

        [DllImport("User32.dll")]
        internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API

        internal delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);
       
        IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)
        {

            if (code < 0) return CallNextHookEx(_nextHookPtr, code, wparam, lparam); //返回,让后面的程序处理该消息 

            if (wparam.ToInt32() == 37 || wparam.ToInt32() == 39) //如果用户输入<-- 或者 -->,左右方向键 
           {
          
                if (wparam.ToInt32() == 37)
                {
                    Car.IsMovingLeft = true;
                    Car.IsMovingRight = false;
                }
                else
                {
                    Car.IsMovingLeft = false;
                    Car.IsMovingRight = true;
                }
                return (IntPtr)1; //直接返回了,该消息就处理结束了
            }
            else
            {
                return IntPtr.Zero; //返回,让后面的程序处理该消息
            }
           
        }

        public void SetHook()
        {
            if (_nextHookPtr != IntPtr.Zero) //已经勾过了
                return;

            HookProc myhookProc = new HookProc(MyHookProc); //声明一个自己的Hook实现函数的委托对象
            _nextHookPtr = SetWindowsHookEx((int)HookType.Keyboard, myhookProc, IntPtr.Zero, GetCurrentThreadId()); //加到Hook链中
            //GC.SuppressFinalize(myhookProc);
            GCHandle.Alloc(myhookProc);///!!!!!阻止回收,否则必定出错
        }

        public void UnHook()
        {
            if (_nextHookPtr != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_nextHookPtr); //从Hook链中取消
                _nextHookPtr = IntPtr.Zero;
            }
        }

    } 

 

   以上案例目的是这样的,我们如果在winForm中使用键盘事件监视案件,的确可以响应按键行为

  但是如果人家拼命按键盘,同时此线程又在做一件不能中断的事情,比如下载,读某个资源,你的应用程序会发生明显的卡,因为在同一线程内他花过多的CPU时间去响应高频率的按键事件

在此过程中,还要当心给回收器回收,GC会错误的以为,不活动,此时只能强行告诉他不要回收

这么做,的确能不给回收,但是这种 非托管资源长时间不给回收 有什么后果,本人能力有限,还不确定。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值