如何运行需要访问ui线程的后台线程

时间:2019-02-13 05:50:31

标签: c# .net multithreading winforms

我期待在程序中添加一个鼠标位置检查模块。 UI有两个Textbox来打印X和Y。它应该异步打印光标位置。

我尝试了BeginInvoke / InvokeThread.isBackgroud = trueBackgroundWorker,但这些方法都没有帮助。

Thread / BackgroundWorker不断发生

  

跨线程错误(符合预期),

BeginInvoke / Invoke的异步问题:UI线程不断消亡。

我还尝试了mousemove事件,但是该事件有效,但是当光标超出窗体边界时,位置跟踪就会停止。

delegate void MP();
private void tracktoggle() {
    MP mp = printMousePosition;
    BeginInvoke(mp); // Or Invoke(mp);
}

private void printMousePosition() {
    while(true) {
       this.Xtext.Text = Mouseposition.X.ToString();
       this.Ytext.Text = Mouseposition.Y.ToString();
    }
}

此代码将UI线程保留在块上。

private async void tracktoggle() {
    Task T = new Task(() => { printMousePosition(); });
    await T;
}

private void printMousePosition() {
    while(true) {
       this.Xtext.Text = Mouseposition.X.ToString();
       this.Ytext.Text = Mouseposition.Y.ToString();
    }
}

这是带有异步/等待的代码。不阻止UI线程,但文本框未更新。 我以为BeginInvoke是Invoke的异步版本:(不起作用

想要异步打印鼠标位置而不会阻塞UI线程。

1 个答案:

答案 0 :(得分:0)

我发现最好的解决方案是使用user32.dll设置WindowsHook。

[DllImport("user32.dll", CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
public static extern int SetWindowsHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

///On the Code 14 is low level mouse hooking id
HookID = SetWindowsHookEx(14, MouseEventFunc, (IntPtr)0, 0/*should be 0, cause we are trying to make global hook);

private void int MouseEventFunc(int nCode, IntPtr w, IntPtr l) {
{
     this.MouseX.Text = MousePosition.X.ToString();
     this.MouseY.Text = MousePosition.Y.ToString();
     return CallNextHookEx(HookID, nCode, w, l);
}

此代码段很好地获取/更新了TextBox。

任何人对此问题都有疑问,请尝试此解决方案