You're better off avoiding the use of tasks and use Microsoft's Reactive Framework (NuGet "System.Reactive.Windows.Threading" for the WPF bits, or "System.Reactive" for the standard bits).
It makes life much easier for this kind of thing. Start by defining static public volatile int SpeedVariable = 200;
and then try this:
IDisposable subscription =
Observable
.Generate(0, x => true, x => x + 1, x => x,
x => TimeSpan.FromMilliseconds(SpeedVariable))
.ObserveOnDispatcher()
.Subscribe(x =>
{
//Some number generated and set to a property
});
You can stop the observable at any time by calling subscription.Dispose();
.
You should even be able to use the value x
in the .Subscribe
method to compute the value of the slider. In this code the value starts as 0
and increments by 1
for each value produced.
Here's version of this code that can be run to see it works:
void Main()
{
IDisposable subscription =
Observable
.Generate(0, x => true, x => x + 1, x => x,
x => TimeSpan.FromMilliseconds(SpeedVariable))
.ObserveOn(Scheduler.Default)
.Subscribe(x => Console.WriteLine(x));
Thread.Sleep(1000);
SpeedVariable = 1000;
Thread.Sleep(5000);
SpeedVariable = 20;
Thread.Sleep(500);
subscription.Dispose();
}
static public volatile int SpeedVariable = 200;
Also, if you want to avoid using a static public volatile
variable then this also works:
var speed = new ReplaySubject<int>(1);
IDisposable subscription =
Observable
.Generate(0, x => true, x => x + 1, x => x,
x => TimeSpan.FromMilliseconds(speed.MostRecent(200).First()))
.ObserveOn(Scheduler.Default)
.Subscribe(x => Console.WriteLine(x));
Thread.Sleep(1000);
speed.OnNext(1000);
Thread.Sleep(5000);
speed.OnNext(20);
Thread.Sleep(500);
subscription.Dispose();
One possible complication with your existing code, the other answers so far, and my answers above, is that you can pause the thread for too long and there's no way to get thread to start again without waiting for the previous pause. Rx provides an easy way to get around this issue. Try this code:
var speed = new Subject<int>();
IDisposable subscription =
speed
.Select(s => Observable.Interval(TimeSpan.FromMilliseconds(s)))
.Switch()
.Select((x, n) => n)
.ObserveOn(Scheduler.Default)
.Subscribe(x => Console.WriteLine(x));
speed.OnNext(200);
Thread.Sleep(1000);
speed.OnNext(1000000); // wait 16.666 minutes
Thread.Sleep(5000);
speed.OnNext(20); // stop previous wait
Thread.Sleep(500);
subscription.Dispose();