We're working with ReactiveExtensions for .Net
We schedule code to run on the Thread Pool like this:
IDisposable myDisposable = Scheduler.Default.Schedule(() =>
{
int count = 0;
while (true)
{
Console.WriteLine(++count);
Thread.Sleep(500);
}
});
Console.ReadKey();
myDisposable.Dispose(); // WHY THIS DO NOTHING?!?!
Console.ReadKey();
As you can see this is a test code that run on a console application.
When I dispose the scheduled code, the code keeps running!
I have no flag that I can check, I cannot add an if statement to stop the scheduled code by myself.
Someone can explain this? Why do I get an IDisposable if it doesn't work? and why I'm not getting some kind of flag (CancellationToken??) for checking inside my code so I can terminate its running in a timely manner?
Thanks!
The issue you're facing is that once your thread gets inside the while (true)
loop it is trapped and can never end. There is nothing magical about .Dispose()
that will stop a thread.
In fact, the disposable is already disposed before you call .Dispose()
. Since you've used an overload of .Schedule
that only runs once the subscription is disposed as soon as the code starts.
What you need to do is use an overload that supports rescheduling. Luckily there's one already there. Try this code:
IDisposable myDisposable = Scheduler.Default.Schedule(0, TimeSpan.Zero, (count, reschedule) =>
{
Console.WriteLine(count);
reschedule(count + 1, TimeSpan.FromSeconds(0.5));
});
This works exactly as you want it to - it correctly disposes.
Now, having said that, you're working with Rx, so you might as well just use the standard observable operators. This works too:
IDisposable myDisposable =
Observable
.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(0.5))
.Subscribe(count => Console.WriteLine(count));
Simple.