2011-08-27 13 views
6

में ठंडे देखने योग्य के बीच अंतर मैं आरएक्स के लिए नया हूं। मैं गर्म observables उपयोग करने के कुछ वास्तविक लाभ देख सकते हैं, लेकिन मैं हाल ही में क्या अंतर सर्दी नमूदार और एक बराबर गणनीय के बीच था (नीचे दिए कोड स्निपेट देखें) पर सवाल ...आरएक्स और सामान्य एन्यूमेरेबल

var resRx = Observable.Range(1, 10); 
    var resOb = Enumerable.Range(1, 10); 

किसी को भी व्याख्या कर सकते हैं कहा गया था बहुत सरलता यह है कि दोनों के बीच क्या अंतर है और मुझे ठंडा अवलोकन करने योग्य बनाम मूल्यवान से क्या लाभ मिलेगा।

उत्तर

15

दोनों के बीच कई अंतर हैं।

कौन 'गणन'

नमूदार (गर्म या ठंडे) के साथ

नियंत्रित करता है, यह निर्धारित करता है कि कब और क्या धागे पर मूल्यों लौटा दिए जाते हैं मानने योग्य है। जब आप अनुरोध करते हैं तो दूसरे हाथ पर एक गणना करने योग्य प्रत्येक मान को प्राप्त करता है और गणना के अनुरोध के धागे पर संसाधित होता है।

कोड फ्लो

प्रसंस्करण enumerables आमतौर पर प्रत्येक पाश के लिए एक में किया जाता है (या कभी कभी प्रगणक हो रही है और थोड़ी देर के पाश का उपयोग)। आपका कोड आम तौर पर जारी रखने से पहले सभी मानों को संसाधित करेगा। पर्यवेक्षकों को कॉलबैक की आवश्यकता होती है। अपने कोड के आगे निष्पादन को अवरुद्ध करना (कंसोल ऐप से बाहर निकलने के लिए कहें) को आपके हिस्से पर अतिरिक्त कोड की आवश्यकता है। First जैसे अवलोकनों के लिए कुछ अवरोधक ऑपरेटर हैं, लेकिन वे सामान्य उपयोग के नियम के बजाय अपवाद हैं।

इस मामूली नमूना कार्यक्रम को एक उदाहरण के रूप में लें। गणना के साथ, अगले मूल्य पर जारी रखने से पहले सभी मान लिखे गए हैं। हालांकि, देखने योग्य मूल्यों को कभी भी लिखे जाने की गारंटी नहीं है। कार्यक्रम समाप्त होने से पहले कितने मूल्य लिखे जाते हैं, यह दौड़ की स्थिति बहुत अधिक है।

static void Main(string[] args) 
{ 
    var xs = Enumerable.Range(1, 10); 
    foreach (var x in xs) 
    { 
     Console.WriteLine(x); 
    } 
    //at this point, all values have been written 

    var ys = Observable.Range(1, 10); 
    ys.Subscribe(y => Console.WriteLine(y)); 
    //at this point, no values have been written (in general) 

    //either add a Console.ReadKey or some sort of wait handle that 
    //is set in the OnCompleted of the observer to get values 
} 

अतुल्यकालिक प्रक्रियाओं

बहुत की तरह आप ब्लॉक और एक नमूदार के लिए प्रतीक्षा, एक IEnumerable कि एक अतुल्यकालिक प्रक्रिया का उपयोग करता लिखने के लिए अतिरिक्त कोड लिखने के लिए कुछ अतिरिक्त काम की आवश्यकता है। यहां वह जगह है जहां दोनों के बीच का अंतर वास्तव में खेल में आता है।

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

+0

धन्यवाद गिडोन ... महान अंतर्दृष्टि। –

6

लगभग सभी संख्याएं जिनका उपयोग आप "शीत" संख्याओं के लिए करते हैं? क्यूं कर? क्योंकि यदि आप संख्यात्मक पर अधिक से अधिक थे। दो बार रेंज करें, आपको 2x संख्याएं मिलेंगी।

यदि संख्यात्मक। श्रेणी एक गर्म गणना योग्य थी, तो यह आपको केवल एक बार सूची देगी और दूसरा फॉरएच खाली होगा।

आरएक्स के लिए, एक शीत अवलोकन करने का मतलब है कि हर बार जब आप सदस्यता लें (आरएक्स में फॉरएच के बराबर), तो आपको सामान की एक नई सूची प्राप्त होगी। जब भी आप सदस्यता लेते हैं, तो हॉटवेव जैसे हॉट वेरिएबल्स आपको ईवेंट की एक नई स्ट्रीम नहीं दे रहे हैं, यह सिर्फ एक ही ईवेंट स्ट्रीम के लिए एक और कनेक्शन होने जा रहा है।

हालांकि आरएक्स का क्या फायदा है? उस श्रेणी को एसिंक अनुरोधों में परिवर्तित करने में सक्षम होने के कारण:

IObservable<Image> fetchImageByIndex(int imageIndexOnSite); 

Observable.Range(0, 10) 
    .SelectMany(x => fetchImageByIndex(x)) 
    .Subscribe(image => saveImageToDisk(image)); 
संबंधित मुद्दे