So, in my mind this is pretty simple. I want to use Interval as a timer to check a WebAPI service every second and then use Distinct to filter it such that I only get notifications when a new value is added.
(ed. I suppose it's good form to highlight early on that I'm using Reactive Extensions for .Net and that's where these terms come from, Interval(...) and Distinct()).
When it comes to implementation I have an async function that returns a Task<PostalCodeModel[]> where the PostalCodeModel is pretty simple dummy model:
public class PostalCodeModel
{
public int PostalCode { get; set; }
public string City { get; set; }
public PostalCodeModel(int code, string name)
{
this.PostalCode = code;
this.City = name;
}
public override string ToString()
{
return string.Format("{0} = {1}", PostalCode, City);
}
}
In my test app I have so far been able to figure out how to create the Interval timer:
var interval = Observable.Interval(TimeSpan.FromSeconds(1));
and using the ToObservable() on the Async method:
///Bad!
private static IObservable<PostalCodeModel[]> CheckPostalCodes()
{
using (ApiClient client = new ApiClient("http://localhost:55457"))
{
return client.GetPostalCodesAsync().ToObservable();
}
}
//Good, thanks Enigmativity!
private static IObservable<PostalCodeModel[]> CheckPostalCodes()
{
return Observable.Using(
() => new ApiClient("http://localhost:55457"),
client => client.GetPostalCodesAsync().ToObservable())
.Take(1);
}
However, I'm having trouble figuring out how to chain these together and where to apply the Distinct method, my attempts so far have been unsucessful:
// No workie :(
var sup = interval.Subscribe(
CheckPostalCodes,
() => Console.WriteLine("Completed"));
Ideally I would do something like:
// No workie :(
Observable.Interval(TimeSpan.FromSeconds(1)).CheckPostalCodes().Distinct()
or similar, but I can't figure out how to do that. Or even if that's a good idea. Eventually the output of this needs to dictate changes in the GUI. And I'm not even sure if using Distinct on an Array of objects works the way I expect it to (only let me know if there is a new value in the array).
As I noted in the comment to Enigmativitys answer below, after correcting the CheckPostalCodes() like he suggested, the subscription was pretty simple, however I did need to add a keySelector to the Distinct call, for it to be able to correctly determine if the returned array is the same. I think simply using array.Count() is sufficient for our purposes, i.e.:
var query = Observable
.Interval(TimeSpan.FromSeconds(1))
.SelectMany(_ => CheckPostalCodes())
.Distinct(array => array.Count());