2011-08-15 16 views
8

मैं एक वर्ग है के लिए एक नमूदार आवरण बनाएँ,एक गैर धागा सुरक्षित वर्ग

public class Test 
{ 
    public int Calc(); 
} 

जो कैल्क के लिए सभी कॉल जिस पर टेस्ट में बनाया गया था के रूप में ही धागे पर करने की आवश्यकता है। मुझे एक बार टेस्ट (महंगे ऑपरेशन) बनाने और कैल्क को कई बार कॉल करने की आवश्यकता है।

मैं एक आवरण मुझे कैल्क asynchronousely फोन देंगे करना चाहते हैं:

public class TestWrapper 
{ 
    private Test _test; 
    public IObservable<int> Calc(); 
} 

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

क्या ऐसा करने के लिए एक और अधिक सुरुचिपूर्ण आरएक्स तरीका है?

उत्तर

4

तो यह संभव है के लिए Test जब TestWrapper बनाई गई है बनाया जाना तो इस वर्ग आपकी आवश्यकताओं को पूरा करने लगता है मैंने इसका परीक्षण किया है और यह उसी धागे पर Test बनाता है जो Calc पर निष्पादित किया गया है। दूसरी ओर, सब्सक्रिप्शन को उसी धागे पर संभाला जाता है क्योंकि testWrapper स्वयं ही (यानी कॉलिंग थ्रेड) पर बनाया गया था।

0

जब Test के अपने उदाहरण बनाकर ThreadLocal<T> वर्ग का उपयोग करें:

var MyTEST = new ThreadLocal<Test>(); 

तो आप किसी भी कॉल के लिए MyTEST.Value.Calc() उपयोग कर सकते हैं ...

एक अन्य विकल्प की टेस्ट सदस्य पर [ThreadStatic] डाल उपयोग करने के लिए है रैपर वर्ग ... देखें http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx

इस पर निर्भर करता है कि आपकोके एक से अधिक उदाहरण की आवश्यकता है या नहींआप इसे Singleton बना सकते हैं।

3

इसलिए टिप्पणियों से और अपने प्रश्न को दोबारा पढ़ने के बाद मैं इकट्ठा करता हूं कि आप लगातार थ्रेड पर कैल्क() को कॉल करना चाहते हैं और वापसी परिणाम IObservable<Int>() के रूप में उपलब्ध हैं?

इस मामले में, मैं Observable.Create का उपयोग Test वर्ग रैप करने के लिए चाहते हैं, और EventLoopScheduler कैल्क को आमंत्रण सुनिश्चित करने के लिए किसी एकल थ्रेड पर हैं।

public class TestWrapper 
{ 
    public TestWrapper(Func<Test> factory) 
    { 
     _scheduler = new EventLoopScheduler(); 
     _test = Observable.Start(factory, _scheduler).First(); 
    } 

    private readonly EventLoopScheduler _scheduler; 
    private readonly Test _test; 

    public IObservable<int> Calc() 
    { 
     return Observable.Start(() => _test.Calc(), _scheduler); 
    } 
} 

यह बहुत की तरह प्रयोग किया जाता है:

var testWrapper = new TestWrapper(() => new Test()); 
testWrapper.Calc().Subscribe(x => { }); 

मैं

public class TestWrapper 
{ 
    private Test _test; 
    public IObservable<int> Calc() 
    { 
    return Observable.Create(obsvr => 
    { 
     var fixedThreadsched = new EventLoopScheduler(); 
     var disp = new BooleanDisposable(); 
     while (!disp.IsDisposed) 
     { 
      fixedThreadsched.Schedule(() => obsvr.OnNext(_test.Calc())); 
     } 

     return disp; 
    }); 
    } 
} 
+0

धन्यवाद, EventLoopScheduler एक ही थ्रेड पर कॉल मार्शल करने की कुंजी है। फिर भी, यह जवाब टेस्टवापर.कैल्क से स्विच करने का तरीका नहीं बताता है जो परीक्षण के लिए यूआई थ्रेड पर निष्पादित किया जाएगा। कैल्क ... –

+0

@ सर्गी - आपकी टिप्पणियों के आधार पर अपडेट किया गया –

+0

यह करीब है ... टुकड़ा गायब है कि आप _test नहीं बनाएं (जो EventLoopScheduler पर किया जाना चाहिए)। हम्म ... तय करना मुश्किल है - आप EventLoopScheduler के साथ पहले थे लेकिन @enigmativity ने सही उत्तर प्रदान किया। धन्यवाद दोस्तों आप दोनों चट्टान! –

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