Reputation: 1286
I am working on a WPF application that runs on an embedded device (.NET Standard 4 for embedded). It has a whole bunch of hardware attached which gets in the way when I'm testing, so I created a DummyHardware interface that just does nothing except print log messages when I run my unit tests, or run stand-alone on my development PC.
So far so good. But: the device has a 4-key keypad which is polled. My dummy keypad class went into an infinite loop when waiting for a key to be pressed, because there were no keys to press :-) So I thought, "Ok, I'll poll the keyboard to see if 1,2,3 or 4 is pressed". But I get the exception
The calling thread must be STA...
when I called Keyboard.IsKeyDown( Key.D1 )
. The keypad polling takes place in a separate thread (to decouple from the generally slow serial comms of the rest of the hardware). Any thoughts on how to proceed? Invoke?
Note: one alternative would be to just skip the "wait for key" test on dummy hardware, but then I don't know which key was pressed and the following code which relies on it won't function correctly. Yuk.
Upvotes: 1
Views: 1304
Reputation: 69979
I have a simple method that handles running on the UI thread for me:
public object RunOnUiThread(Delegate method)
{
return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
Where Dispatcher
is initialised using Dispatcher.CurrentDispatcher
from the UI thread. It can be called from any thread and is used like this:
UiThreadManager.RunOnUiThread((Action)delegate
{
// running on the UI thread
});
Upvotes: 1
Reputation: 6466
You can just set the ApartmentState to be STA. using the Thread.SetApartmentState method
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);
}
}
}
}
Upvotes: 4