放到线程中不管用?什么原因

winform 监听扫码枪,上代码

private void cash_Load(object sender, EventArgs e)
        {
            ScanUseMethed use = new ScanUseMethed();
            use.startScanLinster();
        }
//这样是可以捕获到扫码信息的
        {
            ThreadStart thStart = new ThreadStart(aa); 
            Thread thread = new Thread(thStart);
            thread.Start();
        }

        void aa()
        {
            ScanUseMethed use = new ScanUseMethed();
            use.startScanLinster();
        }
//放到线程中启动 就捕获不到扫码信息 这是为什么?

启动监听的主要代码如下

        public event ScanerDelegate ScanerEvent;
        delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
        private int hKeyboardHook = 0;
        private ScanerCodes codes = new ScanerCodes();
        private HookProc hookproc;
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32", EntryPoint = "GetKeyNameText")]
        private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize);
        [DllImport("user32", EntryPoint = "GetKeyboardState")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("user32", EntryPoint = "ToAscii")]
        private static extern bool ToAscii(int VirtualKey, int ScanCode, byte[] lpKeySate, ref uint lpChar, int uFlags);
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

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

        public ScanCodeHook222()
        {
        }
        public bool Start()
        {
            if (hKeyboardHook == 0)
            {
                hookproc = new HookProc(KeyboardHookProc);

                IntPtr modulePtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
                hKeyboardHook = SetWindowsHookEx(13, hookproc, modulePtr, 0);
            }
            return (hKeyboardHook != 0);
        }
        public bool Stop()
        {
            if (hKeyboardHook != 0)
            {
                return UnhookWindowsHookEx(hKeyboardHook);
            }
            return true;
        }

不是放到线程里面不管用,是因为放到线程里面之后你的aa()函数执行完线程结束了,整个线程资源包括实例化的use也被GC给回收掉了。你可以把你的aa函数改成这样试试:

       void aa()
        {
            ScanUseMethed use = new ScanUseMethed();
            use.startScanLinster();
            while (true)
            {
                Application.DoEvents();
                Thread.Sleep(1);
            }
        }

强制在函数末尾加一个死循环不让你实例化的线程结束。

之所以在UI线程不会出现这样的情况是因为UI线程本来就有一个消息死循环,你的Main函数里面肯定有:Application.Run(new Form1()),这个函数感兴趣的话你可以去看看里面是什么样子的,里面核心就是一个消息的死循环,所以UI线程才不会像你自己实例化的线程那样执行完函数立马结束回收。

A是主程序 B是新建的一个类库,我把启动监听的代码放到了B类库里面,然后在A主程序中去实例化这个类型中的方法去启动就不可以了,这是什么原因呢?

如果要把这些启动方法放到一个类库 应该怎么操作呢, 放到主程序可以 但是放到另外的一个类库就不行 是什么原理呢?谢谢指导