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 Enigmativity
s 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());