I’m trying to detect every time the clipboard data changes. And so, I set a timer and have it continuously check Clipboard.GetText() for changes.
I’m using the following code:
public void WaitForNewClipboardData()
{
//This is in WPF, Timer comes from System.Timers
Timer timer = new Timer(100);
timer.Elapsed += new ElapsedEventHandler(
delegate(object a, ElapsedEventArgs b){
if (Clipboard.GetText() != ClipBoardData)
{
SelectedText.Text = Clipboard.GetText();
ClipBoardData = Clipboard.GetText();
timer.Stop();
}
});
timer.Start();
}
I get the following error when it runs:
Current thread must be set to singlethread apartment (STA) mode before OLE calls can be made.
Does anyone know why?
It’s the threading model of basically any managed Windows GUI application. The thread that is running the code ergo interfacing with the UI thread must be the one and the same. If you maintain the SynchronizationContext of your start up path some where (you can put this in a static varible) you can post messages to it. Those messages will end up executing on the correct thread and you’ll not get this error.
So, basically, when you are working with different threads (i.e. timers and what not) you need to remeber that the original start up thread is special (given that it’s an STA thread). In order to invoke methods on objects that belong to that special thread you go through the SynchronizationContext which I’ve provided as a static member for my App class.
You might also wanna think about using a timer that actually dispatches to the main UI thread, then you wouldn’t have to go trough the hassle of posting to the SynchronizationContext yourself.