We have an implementation for an Ultrasound machine application current where the Ultrasound object is created on the UI’s thread. A Singleton implementation would have been good here, but regardless, isn’t.
Recently, the set methods changed such that they automatically stop and restart the ultrasound machine, which can take between 10-100ms depending on the state of the machine. For most cases, this isn’t too bad of a problem, however it’s still causing the UI thread to block for 100ms. Additionally, these methods are not thread-safe and must be called on the same thread where the object was initialized.
This largest issue this is now causing is unresponsive buttons in the UI, especially sliders which may try to update variables many times as you slide the bar. As a result, sliders especially will stutter and update very slowly as it makes many set calls through databound propeties.
What is a good way to create a thread specifically for the creation and work for this Ultrasound object, which will persist through the lifetime of the application?
A current temporary workaround involves spawning a Timer, and invoking a parameter update once we have detected the slider hasn’t moved for 200ms, however a Timer would then have to be implemented for every slider and seems like a very messy solution which solves unresponsive sliders, but still blocks the UI thread occasionally.
One thing that’s really great about programming the GUI is that you don’t have to worry about multiple threads mucking things up for you (assuming you’ve got
CheckForIllegalCrossThreadCalls = true, as you should). It’s all single-threaded, operating by means of a message pump (queue) that processes incoming messages one-by-one.Since you’ve indicated that you need to synchronize method calls that are not written to be thread-safe (totally understandable), there’s no reason you can’t implement your own message pump to deal with your Ultrasound object.
A naive, very simplistic version might look something like this (the
BlockingCollection<T>class is great if you’re on .NET 4.0 or have installed Rx extensions; otherwise, you can just use a plain vanillaQueue<T>and do your own locking). Warning: this is just a quick skeleton I’ve thrown together just now; I make no promises as to its robustness or even correctness.Then what would happen is: every time you want to interact with your Ultrasound object in some way, you do so through this message pump, by calling
Submitand passing in some action that works with your Ultrasound object. The Ultrasound object then receives all messages sent to it synchronously (by which I mean, one at a time), while operating on its own non-GUI thread.