C# 如何使用Interval作为计时器来检查webAPI服务并返回可观察的新值序列
所以,在我看来这很简单。我想使用Interval作为计时器,每秒检查一次WebAPI服务,然后使用Distinct对其进行过滤,这样我只会在添加新值时收到通知 (ed.我想在前面强调一下,我正在使用.Net的反应式扩展,这就是这些术语的来源,C# 如何使用Interval作为计时器来检查webAPI服务并返回可观察的新值序列,c#,system.reactive,C#,System.reactive,所以,在我看来这很简单。我想使用Interval作为计时器,每秒检查一次WebAPI服务,然后使用Distinct对其进行过滤,这样我只会在添加新值时收到通知 (ed.我想在前面强调一下,我正在使用.Net的反应式扩展,这就是这些术语的来源,Interval(…)和Distinct()) 在实现方面,我有一个异步函数,它返回一个任务,其中后解调是非常简单的虚拟模型: public class PostalCodeModel { public int PostalCode { get; s
Interval(…)
和Distinct()
)
在实现方面,我有一个异步函数,它返回一个任务
,其中后解调
是非常简单的虚拟模型:
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);
}
}
在我的测试应用程序中,到目前为止,我已经能够找出如何创建间隔计时器:
var interval = Observable.Interval(TimeSpan.FromSeconds(1));
并在异步方法上使用ToObservable()
:
///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);
}
理想情况下,我会这样做:
// No workie :(
Observable.Interval(TimeSpan.FromSeconds(1)).CheckPostalCodes().Distinct()
或者类似的,但我不知道怎么做。即使这是个好主意。最终,这个输出需要指示GUI中的更改。我甚至不确定在对象数组中使用Distinct是否能按我期望的方式工作(只知道数组中是否有新值)
正如我在下面对
Enigmativity
s答案的评论中所指出的,在按照他的建议更正了CheckPostalCodes()
之后,订阅非常简单,但是我确实需要向Distinct调用添加一个keySelector,以便它能够正确确定返回的数组是否相同。我认为仅使用array.Count()
就足以满足我们的目的,即:
var query = Observable
.Interval(TimeSpan.FromSeconds(1))
.SelectMany(_ => CheckPostalCodes())
.Distinct(array => array.Count());
您错误地编写了
CheckPostalCodes
方法。using
语句在任何可观察对象订阅之前就已经很好地完成了。您需要使用可观察。请改用方法
另外,如果您只希望API调用返回一个值,请不要忘记添加一个。使用(1)
,以确保在一个返回值之后,可观察的停止
因此,CheckPostalCodes
应该如下所示:
private static IObservable<PostalCodeModel[]> CheckPostalCodes()
{
return
Observable
.Using(
() => new ApiClient("http://localhost:55457"),
client => client.GetPostalCodesAsync().ToObservable())
.Take(1);
}
}
让我知道这是否对您有效。这可以创建序列,但正如我担心的那样,Distinct不会“深入比较”数组,我会得到一个相同数组值的重复序列,即订阅:query.Subscribe(数组=>Console.WriteLine($”{DateTime.Now}{string.Join(,,(object[])array})
我重复了一些类似的内容:11.5.2017 13:15:36 110=Name1,210=Name2 11.5.2017 13:15:37 110=Name1,210=Name2
我想知道我是否需要做一个比较器,如下面的答案:-或者数组的某个地方存在比较器吗?实际上,我想这就足够了,由于我们在另一端控制向数组添加的内容/方式:var query=Observable.Interval(TimeSpan.FromSeconds(1)).SelectMany(=>CheckPostalCodes()).Distinct(array=>array.Count())代码>你能解释为什么需要Take(1)吗?如果没有包含它,会不会有内存泄漏?另外,处理异步调用中的错误的最佳/正确方法是什么,即如果服务超时或返回OK以外的任何内容(毕竟是HTTP服务)?
private static IObservable<PostalCodeModel[]> CheckPostalCodes()
{
return
Observable
.Using(
() => new ApiClient("http://localhost:55457"),
client => client.GetPostalCodesAsync().ToObservable())
.Take(1);
}
}
var query =
Observable
.Interval(TimeSpan.FromSeconds(1.0))
.SelectMany(n => CheckPostalCodes())
.Distinct();