C# WPF:轮询键盘

C# WPF:轮询键盘,c#,wpf,multithreading,C#,Wpf,Multithreading,我正在开发一个在嵌入式设备上运行的WPF应用程序(.NET Standard 4 for embedded)。它附带了一大堆硬件,在我测试时会遇到阻碍,所以我创建了一个DummyHardware接口,当我运行单元测试或在我的开发PC上独立运行时,它除了打印日志消息之外什么都不做 到目前为止还不错。但是:该设备有一个4键键盘,可以进行轮询。我的虚拟键盘类在等待按键时进入无限循环,因为没有按键可按:-),所以我想,“好吧,我会轮询键盘,看看是按了1、2、3还是4”。但我有个例外 调用线程必须是STA

我正在开发一个在嵌入式设备上运行的WPF应用程序(.NET Standard 4 for embedded)。它附带了一大堆硬件,在我测试时会遇到阻碍,所以我创建了一个DummyHardware接口,当我运行单元测试或在我的开发PC上独立运行时,它除了打印日志消息之外什么都不做

到目前为止还不错。但是:该设备有一个4键键盘,可以进行轮询。我的虚拟键盘类在等待按键时进入无限循环,因为没有按键可按:-),所以我想,“好吧,我会轮询键盘,看看是按了1、2、3还是4”。但我有个例外

调用线程必须是STA

当我调用
Keyboard.IsKeyDown(Key.D1)
时。键盘轮询在一个单独的线程中进行(与硬件其余部分通常较慢的串行通信分离)。关于如何进行有什么想法吗?调用


注意:一种替代方法是跳过虚拟硬件上的“等待键”测试,但我不知道按下了哪个键,并且依赖它的以下代码将无法正常工作。Yuk.

您可以将ApartmentState设置为STA。使用Thread.SetApartmentState方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace staThread
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread keyboardThread;

        public MainWindow()
        {
            InitializeComponent();
            keyboardThread = new Thread(new ThreadStart(KeyboardThread));
            keyboardThread.SetApartmentState(ApartmentState.STA);
            keyboardThread.Start();
        }

        void KeyboardThread()
        {
            while (true)
            {
                if (Keyboard.IsKeyDown(Key.A))
                {
                }

                Thread.Sleep(100);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间线程
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
线程键盘线程;
公共主窗口()
{
初始化组件();
键盘线程=新线程(新线程开始(键盘线程));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while(true)
{
如果(键盘.IsKeyDown(键.A))
{
}
睡眠(100);
}
}
}
}

您只需将ApartmentState设置为STA即可。使用Thread.SetApartmentState方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace staThread
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread keyboardThread;

        public MainWindow()
        {
            InitializeComponent();
            keyboardThread = new Thread(new ThreadStart(KeyboardThread));
            keyboardThread.SetApartmentState(ApartmentState.STA);
            keyboardThread.Start();
        }

        void KeyboardThread()
        {
            while (true)
            {
                if (Keyboard.IsKeyDown(Key.A))
                {
                }

                Thread.Sleep(100);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间线程
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
线程键盘线程;
公共主窗口()
{
初始化组件();
键盘线程=新线程(新线程开始(键盘线程));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while(true)
{
如果(键盘.IsKeyDown(键.A))
{
}
睡眠(100);
}
}
}
}

我有一个简单的方法来处理在UI线程上运行的问题:

public object RunOnUiThread(Delegate method)
{
    return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
其中,使用UI线程中的
Dispatcher.CurrentDispatcher
初始化
Dispatcher
。它可以从任何线程调用,使用方式如下:

UiThreadManager.RunOnUiThread((Action)delegate
{
    // running on the UI thread
});

我有一个简单的方法来处理在UI线程上运行的问题:

public object RunOnUiThread(Delegate method)
{
    return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
其中,使用UI线程中的
Dispatcher.CurrentDispatcher
初始化
Dispatcher
。它可以从任何线程调用,使用方式如下:

UiThreadManager.RunOnUiThread((Action)delegate
{
    // running on the UI thread
});

谢谢安迪,我喜欢解决方案如此简单的时候:-)谢谢安迪,我喜欢解决方案如此简单的时候:-)