2013-07-21 3 views
7

मैं वर्तमान में आरएक्स .NET के साथ समवर्तीता के आसपास अपने सिर को लपेटने और कुछ से भ्रमित होने की कोशिश कर रहा हूं। मैं समानांतर में चार अपेक्षाकृत धीमे कार्यों को चलाने के लिए चाहता हूं, इसलिए मुझे लगता है कि NewThreadScheduler.Default जाने का तरीका होगा, क्योंकि यह "एक ऑब्जेक्ट का प्रतिनिधित्व करता है जो एक अलग थ्रेड पर काम की प्रत्येक इकाई को शेड्यूल करता है।"NewThreadScheduler.Default शेड्यूल सभी थ्रेड पर काम करता है

यहाँ मेरी सेटअप कोड है:

Starting. Thread 1 
Last line. Thread 1 
1 Thread 3 
2 Thread 3 
3 Thread 3 
4 Thread 3 
Done. Thread 3 

सभी काम है:

static void Test() 
    { 
     Console.WriteLine("Starting. Thread {0}", Thread.CurrentThread.ManagedThreadId); 

     var query = Enumerable.Range(1, 4); 
     var obsQuery = query.ToObservable(NewThreadScheduler.Default); 
     obsQuery.Subscribe(DoWork, Done); 

     Console.WriteLine("Last line. Thread {0}", Thread.CurrentThread.ManagedThreadId); 
    } 

    static void DoWork(int i) 
    { 
     Thread.Sleep(500); 
     Console.WriteLine("{0} Thread {1}", i, Thread.CurrentThread.ManagedThreadId); 
    } 

    static void Done() 
    { 
     Console.WriteLine("Done. Thread {0}", Thread.CurrentThread.ManagedThreadId); 
    } 

मैं "एक्स थ्रेड Y" ग्रहण उत्पादन एक अलग धागा आईडी हर बार, फिर भी वास्तविक उत्पादन है होगा अनुक्रमिक क्रम में एक ही नए धागे पर एक होने के नाते, जो मैं उम्मीद नहीं कर रहा था।

मुझे लगता है कि मुझे कुछ याद आ रहा है, लेकिन मैं यह नहीं समझ सकता कि क्या।

उत्तर

8

एक अवलोकन योग्य क्वेरी के लिए दो भाग हैं, Query स्वयं और Subscription। (यह भी ObserveOn और SubscribeOn ऑपरेटरों के बीच अंतर है।)

आपका Query यह एक नमूदार बनाता है कि कि इस प्रणाली के लिए डिफ़ॉल्ट NewThreadScheduler पर मूल्यों पैदा करता

Enumerable 
    .Range(1, 4) 
    .ToObservable(NewThreadScheduler.Default); 

है।

आपका सदस्यता

obsQuery.Subscribe(DoWork, Done); 

है यह Query और Done द्वारा उत्पादित प्रत्येक मान के लिए DoWork चलता है जब एक OnComplete कॉल के साथ Query खत्म। मुझे नहीं लगता कि सब्सक्राइब विधि में फ़ंक्शंस को किस थ्रेड पर कॉल किया जाएगा, इस बारे में कोई गारंटी है, यदि प्रैक्टिस के सभी मान उसी थ्रेड पर उत्पादित होते हैं जो सब्सक्रिप्शन थ्रेड पर चल रहा है। ऐसा प्रतीत होता है कि वे इसे भी बना रहे हैं, इसलिए सभी सब्सक्रिप्शन कॉल उसी थ्रेड पर बनाई गई हैं जो बहुत सी सामान्य बहु-थ्रेडिंग त्रुटियों से छुटकारा पाने के लिए संभवतः होती है।

तो तुम दो मुद्दे हैं, एक, अपने प्रवेश के साथ है अगर आप बदलना आपके Query

को

Enumerable 
    .Range(1, 4) 
    .Do(x => Console.WriteLine("Query Value {0} produced on Thread {1}", x, Thread.CurrentThread.ManagedThreadId); 
    .ToObservable(NewThreadScheduler.Default); 
आप एक नया धागा पर उत्पादित प्रत्येक मान दिखाई देगा।

अन्य मुद्दा आरएक्स के इरादे और डिजाइन में से एक है। यह इरादा है कि Query लंबी चल रही प्रक्रिया है और Subscription एक छोटी सी विधि है जो परिणामों से संबंधित है। यदि आप एक लंबे समय तक चलने वाले फ़ंक्शन को आरएक्स ऑब्जर्वेबल के रूप में चलाने के लिए चाहते हैं तो आपका सर्वोत्तम विकल्प Observable.ToAsync का उपयोग करना है।

+0

इसके लिए धन्यवाद। न केवल आप यह बता रहे हैं कि मैं क्या गलत कर रहा हूं, लेकिन मुझे लगता है कि आरएक्स के इरादे के बारे में आप जो कहते हैं, वह बहुत समझ में आता है। –

+0

उपर्युक्त उत्तर पुराना प्रतीत होता है, क्या विधि अब उपलब्ध नहीं है। – VivekDev

+0

काम करने के लिए विधि विधि के लिए, आपको System.Interactive nuget पैकेज स्थापित करने की आवश्यकता है – VivekDev

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

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