यह किसी अन्य प्रणाली को मतदान करने के लिए आरएक्स का उपयोग करने का एक काफी क्लासिक मामला है। अधिकांश लोग Observable.Interval
का उपयोग अपने जाने-माने ऑपरेटर के रूप में करेंगे, और अधिकांश के लिए यह ठीक होगा।
हालांकि आपके पास टाइमआउट पर पुनः आवश्यकताएं हैं और पुनः प्रयास करें। इस मामले मुझे लगता है कि आप ऑपरेटरों के संयोजन का उपयोग बेहतर कर रहे हैं:
Observable.Timer
आप एक निर्दिष्ट समय
Timeout
की पहचान करने और करने के लिए आपकी क्वेरी को निष्पादित करने की अनुमति के लिए डेटाबेस क्वेरी, जो करने के लिए
ToObservable()
लंघन है अपने Task
परिणामों को एक अवलोकन अनुक्रम में मैप करें।
Retry
आपको टाइमआउट
Repeat
के बाद पुनर्प्राप्त करने के लिए आपको सफल डेटाबेस प्रश्नों के बाद जारी रखने की अनुमति देने के लिए अनुमति देता है। यह पिछले डेटाबेस क्वेरी के पूरा होने और अगले के प्रारंभ के बीच प्रारंभिक अवधि/अंतर भी रखेगा।
यह काम कर LINQPad टुकड़ा आप दिखाना चाहिए क्वेरी ठीक से काम करता है:
void Main()
{
var pollingPeriod = TimeSpan.FromSeconds(5);
var dbQueryTimeout = TimeSpan.FromSeconds(10);
//You will want to have your Rx query timeout after the expected silence of the timer, and then further maximum silence.
var rxQueryTimeOut = pollingPeriod + dbQueryTimeout;
var scheduler = new EventLoopScheduler(ts => new Thread(ts) { Name = "DatabasePoller" });
var query = Observable.Timer(pollingPeriod, scheduler)
.SelectMany(_ => DatabaseQuery().ToObservable())
.Timeout(rxQueryTimeOut, Observable.Return("Timeout"), scheduler)
.Retry() //Loop on errors
.Repeat(); //Loop on success
query.StartWith("Seed")
.TimeInterval(scheduler) //Just to debug, print the timing gaps.
.Dump();
}
// Define other methods and classes here
private static int delay = 9;
private static int delayModifier = 1;
public async Task<string> DatabaseQuery()
{
//Oscillate the delay between 3 and 12 seconds
delay += delayModifier;
var timespan = TimeSpan.FromSeconds(delay);
if (delay < 4 || delay > 11)
delayModifier *= -1;
timespan.Dump("delay");
await Task.Delay(timespan);
return "Value";
}
परिणाम की तरह लग रहे:
Seed 00:00:00.0125407
Timeout 00:00:15.0166379
Timeout 00:00:15.0124480
Timeout 00:00:15.0004520
Timeout 00:00:15.0013296
Timeout 00:00:15.0140864
Value 00:00:14.0251731
Value 00:00:13.0231958
Value 00:00:12.0162236
Value 00:00:11.0138606
नमूने के महत्वपूर्ण हिस्सा है ....
var query = Observable.Timer(TimeSpan.FromSeconds(5), scheduler)
.SelectMany(_ => DatabaseQuery().ToObservable())
.Timeout(rxQueryTimeOut, Observable.Return("Timeout"), scheduler)
.Retry() //Loop on errors
.Repeat(); //Loop on success
संपादित करें: यहां इस समाधान पर पहुंचने का एक और विवरण दिया गया है। https://github.com/LeeCampbell/RxCookbook/blob/master/Repository/Polling.md
स्रोत
2015-11-16 16:04:43
क्या आप अधिक जानकारी जोड़ सकते हैं? क्वेरी वापस क्या डेटा प्राप्त करती है? क्या क्वेरी एक ऑब्जेक्ट लौटाती है? टाइमआउट के मामले में आप कहते हैं कि आप एक नई क्वेरी लॉन्च करना चाहते हैं, वह क्वेरी क्या है? –