我必须轮询数据库,直到它包含有效的数据。
要做到这一点,我有一个应该每隔n
秒查询一次的存储库,以获得我自己的实体,称为DestinationResponse
。
class DestinationResponse
{
bool HasDestination { get; set; }
bool Destination { get; set; }
}
当DestinationResponse的属性HasDestination
改为true
时,会返回Destination
。
所以,我的可观察序列应该得到所有响应等待HasDestination=true
的响应。它基本上等待HasDestination设置为true的响应。发生这种情况时,它会返回它并完成序列。它最多只会推送一个元素!
我目前的做法是:
var pollingPeriod = TimeSpan.FromSeconds(n);
var scheduler = new EventLoopScheduler(ts => new Thread(ts) {Name = "DestinationPoller"});
var observable = Observable.Interval(pollingPeriod, scheduler)
.SelectMany(_ => destinationRepository.GetDestination().ToObservable())
.TakeWhile(response => !response.HasDestination)
.TakeLast(1)
.Select(response => response.Destination);
我知道我错了,主要是因为即使最后一次调用GetDestination还没有完成,Interval调用也会继续生成。
注意:
repository.GetDestination()
返回Task<DestinationResponse>
,它实际上会查询数据库。
答案 0 :(得分:2)
将Database polling with Reactive Extensions的答案与您的示例代码合并,我认为可以为您提供所需内容。
var pollingPeriod = TimeSpan.FromSeconds(n);
var scheduler = new EventLoopScheduler(ts => new Thread(ts) {Name = "DestinationPoller"});
var query = Observable.Timer(pollingPeriod , scheduler)
.SelectMany(_ => destinationRepository.GetDestination().ToObservable())
.TakeWhile(response => response.HasDestination)
.Retry() //Loop on errors
.Repeat() //Loop on success
.Select(response => response.Destination)
.Take(1);
答案 1 :(得分:0)
此代码可能是我想要的查询。你觉得怎么样?
private IObservable<Destination> CreateOrderDestinationObservable(string boxId, int orderId)
{
var pollingPeriod = TimeSpan.FromSeconds(DestinationPollingDelay);
var scheduler = new EventLoopScheduler(ts => new Thread(ts) {Name = "DestinationPoller"});
var observable = Observable.Timer(pollingPeriod, scheduler)
.SelectMany(_ => externalBridgeRepository.GetDestination(boxId, orderId).ToObservable())
.Where(response => response.HasDestination)
.Retry()
.Repeat()
.Take(1)
.Select(response => response.Destination);
return observable;
}