views:

99

answers:

3

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.

+3  A: 

You should maintain a dedicated UltraSound thread, which creates the UltraSound object and then listens for callbacks from other threads.

You should maintain a thread-safe queue of delegates and have the UltraSound thread repeatedly execute and remove the first delegate in the queue.

This way, the UI thread can post actions to the queue, which will then be executed asynchronously by the UltraSound thread.

SLaks
Looks like we had the same suggestion, but yours is way more concise. Also, probably more correct, as I did *not* double-check that code I included in mine.
Dan Tao
A: 

I'm not sure I fully understand the setup, but here is my attempt at a solution:

How about having the event handler for the slider check the last event time, and wait for 50ms before processing a user adjustment (only process the most recent value).

Then have a thread using a while loop and waiting on an AutoResetEvent trigger from the GUI. It would then create the object and set it?

Jess
+4  A: 
Dan Tao
+1 Looks correct to me. This is how I would do it as well.
Brian Gideon
+1, I implemented this same approach for interaction with an unmanaged API that would actually check what thread you were calling it from and throw exceptions if you weren't on the same thread. It's a bit awkward, but it works well. I called mine `SingleThreadTaskRunner` and unfortunately implemented it before BlockingCollection and rolled my own synchronization with associated subtle race condition bugs.
Dan Bryant