views:

60

answers:

4

My C# WinForms UI has some parameters that the user can adjust using sliders. Many parts of the UI can interactively update based on the slider values. However, some parts require a longer calculation that requires some overhead to set up. I would like to only initiate this update process once the user has stopped moving the sliders for, say, 2 seconds. What's the best way to do this?

A: 

I would have a private instance member referencing a thread timer. When the timer hits 2 seconds, the event containing the calculations would fire. All sliders would have an change listener that would set the timer to 0 and start the timer.

Jarrett Meyer
+1  A: 

You could use a Timer control that resets the UI if any anything has changes after 2 seconds.

The timer would also check a variable that is flagged after every change, so only when the flag has not changes and timer times out, the UI is upated.

Mark Redman
+2  A: 

The Reactive Framework would be perfect for that. If you have C# 3.5, you could use it.

Observable.FromEvent<ScrollEventArgs>(vScrollBar1, "Scroll")
    .Throttle(TimeSpan.FromSeconds(2)) // Wait for two second alter all Scroll event ended
    .ObserveOnWindowsForms() // Make the lambda expression run on the UI thread
    .Subscribe(
        e =>
        {
            // Update your stuff
            labelControl1.Text = e.EventArgs.NewValue.ToString();
        });

You can get rid of the ObserveOnWindowsForms call if you don't want to make your UI to hang while running the lamda, but make sure that you properly access your UI component to avoid cross-threading exception.

Pierre-Alain Vigeant
Neat. I was just compiling my list of things to look at over the holidays - I'd forgotten I wanted to learn the Rx framework and this reminded me. Thanks.
Matt Breckon
I like this solution even though fluent programming makes me sad. The big downer is that it requires the Rx library.
Eric
A: 

You need to use this timer: System.Windows.Forms.Timer. Why? It executes on the UI thread meaning you don't have to use InvokeRequired or BeginInvoke to execute your UI updating code on the UI thread.

Will