Let\'s pretend I have something like this:
And something like this:
publ
While I kind of agree with James World, I think you can Do Better, if we use just a bit of mutable state. What if DoWork looked like this:
AsyncSubject doingWork;
public IObservable DoWork()
{
if (doingWork != null) return doingWork;
doingWork = Observable.Start(() => {
// XXX: Do work
Thread.Sleep(1000);
// We only kick off this 1sec timeout *after* we finish doing work
Observable.Timer(TimeSpan.FromSeconds(1.0), DispatcherScheduler.Instance)
.Subscribe(_ => doingWork = null);
});
return doingWork;
}
Now, DoWork debounces itself Automagically™, and we can get rid of this await-in-Subscribe silliness; we set the throttle to 250ms to be Quick-But-Not-Too-Quick.
This initially appears to violate requirement #5 above, but we've ensured that anyone calling DoWork too quickly just gets the previous run's results - the effect will be that DoWork will be called many times, but not necessarily do anything. This ensures though, that if we aren't doing work, we won't have a 1sec delay after the user stops typing, like Throttle(1.seconds)
would
Observable.FromEventPattern(this, "PropertyChanged")
.Where(x => x.EventArgs.PropertyName.Equals("Text"))
.Throttle(TimeSpan.FromMilliseconds(250), DispatcherScheduler.Instance)
.SelectMany(_ => DoWork())
.Catch(ex => {
Console.WriteLine("Oh Crap, DoWork failed: {0}", ex);
return Observable.Empty();
})
.Subscribe(_ => Console.WriteLine("Did work"));