2012-06-15 15 views
7

मैं अपने विचारों में से किसी एक में कुछ थ्रॉटलिंग व्यवहार को लागू करने के लिए देख रहा हूं। यह एक चांदी का आवेदन है, हालांकि मुझे नहीं लगता कि यह विशेष रूप से महत्वपूर्ण है।इवेंट थ्रॉटलिंग/क्यूइंग - प्रतिक्रियाशील एक्सटेंशन?

  • Property1
  • Property2
  • Property3

जब भी इन गुणों में से एक अद्यतन किया जाता है, एक ताज़ा आवश्यक है:

तीन गुणों के साथ एक वर्ग पर विचार करें।

private void Refresh() 
{ 
    //Call out to the server, do something when it comes back 
} 

मेरे लक्ष्यों इस प्रकार हैं: एक ताज़ा प्रगति पर है

  • हैं, तो हम आदर्श सर्वर से कॉल रद्द कर देना चाहिए, और
  • एक नया अनुरोध जारी एक संपत्ति बदले जाने पर हमें कुछ छोटी खिड़की (शायद 0.1 सेकंड) छोड़नी चाहिए जहां हम अतिरिक्त बदलावों की प्रतीक्षा करते हैं। इस तरह, यदि एकाधिक गुण तेजी से बदल दिए जाते हैं (उदाहरण के लिए, प्रोग्रामेटिक रूप से) हम अनुरोध के साथ सर्वर को स्पैम नहीं करते हैं। प्रत्येक परिवर्तन पर रीसेट करने के लिए उस 0.1 सेकंड विंडो के लिए ठीक है, लेकिन आवश्यक नहीं है।

यदि यह महत्वपूर्ण है, तो मैं सर्वर कॉल के लिए चैनलफ़ैक्टरी कार्यान्वयन का उपयोग कर रहा हूं।

इसे पूरा करने के लिए मैं किस प्रकार के पैटर्न का उपयोग कर सकता हूं? क्या यह कुछ प्रतिक्रियाशील एक्सटेंशन मेरी मदद कर सकता है?

संपादित करें:

सही रूप में पॉल के जवाब अंकन। जबकि ReactiveUI वर्तमान में Silverlight5 के खिलाफ काम नहीं करता है, यह आरएक्स का उपयोग कर समस्या को हल करने के लिए दृष्टिकोण/संरचना चरणों को स्पष्ट रूप से रेखांकित करता है।

+1

आरएक्स निश्चित रूप से इस का समर्थन करता है, http://rxwiki.wikidot.com/101samples#toc29 देखते हैं - कार्य –

उत्तर

6

का तरीका यहां बताया ReactiveUI के साथ ऐसा होता है:

IObservable<TheData> FetchNewData() 
{ 
    // TODO: Implement me 
} 

this.WhenAny(x => x.Property1, x => x.Property2, x => x.Property3, (x,y,z) => Unit.Default) 
    .Throttle(TimeSpan.FromMilliseconds(200), RxApp.DeferredScheduler) 
    .Select(x => FetchNewData()) 
    .Switch() // We only care about the req corresp. to latest values of Prop1-3 
    .ToProperty(this, x => x.Data); 

अद्यतन: यहाँ गारंटी करने के लिए कैसे है कि वहाँ केवल एक ही एक समय में चल रहा है, चेतावनी है कि आप बाहर के आदेश प्राप्त कर सकते हैं के साथ है परिणाम है।

this.WhenAny(x => x.Property1, x => x.Property2, x => x.Property3, (x,y,z) => Unit.Default) 
    .Throttle(TimeSpan.FromMilliseconds(200), RxApp.DeferredScheduler) 
    .Select(_ => Observable.Defer(() => FetchNewData())) 
    .Merge(1) 
    .ToProperty(this, x => x.Data); 

व्यवहार आप का वर्णन है, वास्तव में, शायद वांछनीय नहीं किया जाएगा के बाद से यदि गुणों को बदलने रखने के लिए, आप पुराने अनुरोधों का एक कतार के साथ खत्म हो जाएगा जारी करने के लिए - यदि आप एक तरह कुछ बना तो आप इस अनुकूलन कर सकता है "बफरिंगस्विच()" ऑपरेटर जिसने अपने परिणामों को वापस नहीं किया जब तक कि यह सुनिश्चित न हो कि इसमें कोई बदलाव नहीं था - जो वास्तव में लिखने के लिए अच्छा होगा।

कहानी का नैतिक, Async जटिल है ™ :)

+0

से CancellationToken पर एक नज़र डालें - रद्द इसके बारे में धन्यवाद, ऐसा लगता है कि मुझे पहली नज़र में क्या चाहिए। क्या यह चांदी की रोशनी के लिए मान्य है? मुझे यह कोशिश करने के लिए WhenAny एक्सटेंशन विधि नहीं मिल रही है। –

+0

@SununRowan: वह एक्सटेंशन ReactiveUI (http://www.reactiveui.net) से है। पिछले संस्करण (v2) सिल्वरलाइट का समर्थन करते हैं। वर्तमान संस्करण (v3) नहीं है। विशेष रूप से यदि आप एमवीवीएम कर रहे हैं, तो यह वास्तव में एक महान पुस्तकालय है। –

+0

धन्यवाद, मैं इसे देख लूंगा! किसी कारण से मेरे दिमाग ने "प्रतिक्रियाशील एक्सटेंशन" के साथ "प्रतिक्रियाशील यूआई" को बदल दिया। (मुझे लाइब्रेरी से अवगत नहीं था।) –

संबंधित मुद्दे