हालांकि, जबकि eventStream अभी भी मौजूद है और स्मृति में रखा जाना चाहिए, वहाँ 2 नए इस विधि के द्वारा बनाई गई IObservables रहा है - एक विधि कहाँ() द्वारा दिया कि शायद eventStream द्वारा स्मृति में आयोजित किया जाता है, और एक कास्ट() विधि द्वारा लौटाया गया है जो संभवतः कहां() विधि द्वारा लौटाए गए द्वारा स्मृति में आयोजित किया जाता है।
आपके पास यह पिछड़ा है। चलो चल रहा है की श्रृंखला के माध्यम से चलो चलते हैं।
IObservable<T> eventStream; //you have this defined and assigned somewhere
public IDisposable Subscribe<T>(IObserver<T> observer)
{
//let's break this method into multiple lines
IObservable<T> whereObs = eventStream.Where(e => e is T);
//whereObs now has a reference to eventStream (and thus will keep it alive),
//but eventStream knows nothing of whereObs (thus whereObs will not be kept alive by eventStream)
IObservable<T> castObs = whereObs.Cast<T>();
//as with whereObs, castObs has a reference to whereObs,
//but no one has a reference to castObs
IDisposable ret = castObs.Subscribe(observer);
//here is where it gets tricky.
return ret;
}
क्या ret
करता है या एक संदर्भ नहीं है विभिन्न observables के क्रियान्वयन पर निर्भर। मैंने आरएक्स लाइब्रेरी में रिफ्लेक्टर में जो देखा है और ऑपरेटर मैंने खुद को लिखा है, ज्यादातर ऑपरेटर ऐसे डिस्पोजेबल वापस नहीं लौटाते हैं जिनके पास ऑपरेटर का संदर्भ स्वयं ही दिखता है।
उदाहरण के लिए, Where
की एक बुनियादी कार्यान्वयन की तरह कुछ (संपादक में सीधे टाइप किया, कोई त्रुटि हैंडलिंग)
IObservable<T> Where<T>(this IObservable<T> source, Func<T, bool> filter)
{
return Observable.Create<T>(obs =>
{
return source.Subscribe(v => if (filter(v)) obs.OnNext(v),
obs.OnError, obs.OnCompleted);
}
}
सूचना है कि डिस्पोजेबल लौटे पर्यवेक्षक के माध्यम से फिल्टर समारोह के लिए एक संदर्भ होगा होगा यह बनाया गया है, लेकिन Where
देखने योग्य नहीं होगा। Cast
को उसी पैटर्न का उपयोग करके आसानी से कार्यान्वित किया जा सकता है। संक्षेप में, ऑपरेटर पर्यवेक्षक रैपर कारखानों बन जाते हैं।
इस सवाल का सब कुछ इस बात का निहितार्थ है कि मध्यवर्ती IObservables विधि विधि के अंत तक कचरा संग्रह के लिए योग्य हैं। फ़िल्टर फ़ंक्शन Where
तक पास रहता है जब तक कि सदस्यता करता है, लेकिन सदस्यता के निपटारे या पूरा होने के बाद, केवल eventStream
बनी हुई है (माना जाता है कि यह अभी भी जीवित है)।
सुपरकैट की टिप्पणी के लिए संपादित करें, चलिए देखते हैं कि कंपाइलर इसे फिर से लिख सकता है या आप इसे बंद किए बिना कैसे कार्यान्वित करेंगे।
class WhereObserver<T> : IObserver<T>
{
WhereObserver<T>(IObserver<T> base, Func<T, bool> filter)
{
_base = base;
_filter = filter;
}
IObserver<T> _base;
Func<T, bool> _filter;
void OnNext(T value)
{
if (filter(value)) _base.OnNext(value);
}
void OnError(Exception ex) { _base.OnError(ex); }
void OnCompleted() { _base.OnCompleted(); }
}
class WhereObservable<T> : IObservable<T>
{
WhereObservable<T>(IObservable<T> source, Func<T, bool> filter)
{
_source = source;
_filter = filter;
}
IObservable<T> source;
Func<T, bool> filter;
IDisposable Subscribe(IObserver<T> observer)
{
return source.Subscribe(new WhereObserver<T>(observer, filter));
}
}
static IObservable<T> Where(this IObservable<T> source, Func<T, bool> filter)
{
return new WhereObservable(source, filter);
}
आप देख सकते हैं कि पर्यवेक्षक नमूदार है कि यह उत्पन्न और नमूदार पर्यवेक्षकों यह बनाता है ट्रैक करने के लिए कोई ज़रूरत नहीं है के लिए किसी भी संदर्भ की जरूरत नहीं है। हमने अपनी सदस्यता से वापस आने के लिए कोई नया आईडीस्पोजेबल भी नहीं बनाया है।
असल में, आरएक्स में अज्ञात पर्यवेक्षक/पर्यवेक्षक के लिए कुछ वास्तविक कक्षाएं हैं जो प्रतिनिधियों को लेती हैं और उन प्रतिनिधियों को इंटरफ़ेस कॉल अग्रेषित करती हैं। यह उन प्रतिनिधियों को बनाने के लिए बंद का उपयोग करता है। कंपाइलर को कक्षाओं को उत्सर्जित करने की आवश्यकता नहीं होती है जो वास्तव में इंटरफेस को लागू करते हैं, लेकिन अनुवाद की भावना एक ही है।
मैं इसे सत्यापित करने में सक्षम नहीं हूं, लेकिन मुझे संदेह है कि सदस्यता आपको कुछ देता है, जब निपटान किया जाता है, तो सभी अस्थायी अवलोकनों का भी निपटान करेगा। –
मैंने सोचा कि शुरुआत में भी, लेकिन मेरे प्रश्न की अंतिम वाक्य पढ़ें।अस्थायी पर्यवेक्षकों को पता है कि किसी और ने उनके लिए कोई संदर्भ नहीं लिया है और किसी बिंदु पर बाद में सदस्यता ली जा सकती है? – Tyson
मुझे नहीं पता कि वास्तव में क्या होता है, क्षमा करें। लेकिन एक तरीका यह _could_ काम है। सदस्यता वृद्धि संख्याओं (जो अभिभावक श्रृंखला को बुलबुला करता है) सदस्यता लें। और उन्हें कम करें, अगर यह शून्य हो जाता है तो इसका निपटान करें। –