2013-08-02 13 views
5

मैं एक व्यवहार विषयएक व्यवहार विषय

var source = new BehaviorSubject<int>(0); 

मैं तो प्रक्रिया है पर अपवाद को संभालने के लिए कैसे इस तरह

var withErrors = source 
      .Select(v => 
      { 
       if (v == 2) 
       { 
        throw new Exception("Ouch "); 
       } 
       return v; 
      }) 

मैं इस तरह से withErrors की सदस्यता के लिए चाहते हैं कुछ के साथ स्रोत है कि मैं त्रुटियों को छोड़ सकते हैं। इस तरह पकड़ने के साथ एक प्रयास।

public IObservabe<int> SkipError(IObservable<T> source){ 

    return source 
     .Catch(e=>SkipErrors(source.Skip(1)); 
} 

और फिर इसे कहते इस प्रकार

var withoutErrors = SkipError(withErrors); 

छोड़ें व्यवहार विषय पर पिछले त्रुटि दोहराने से बचें करने का प्रयास है, लेकिन अफसोस यह कि जिस तरह से काम नहीं करता। छोड़ें त्रुटियों पर छोड़ नहीं है बल्कि केवल वैध डेटा पर है, इसलिए व्यवहार विषय में वर्तमान स्थिति से त्रुटि प्राप्त हो रही है।

क्या लेखन का एक चालाक तरीका है छोड़ें जो त्रुटियों पर भी छोड़ देगा। कुछ मुझे बताता है कि यह संभव नहीं है लेकिन उम्मीद है कि मैं गलत हूं

+1

असल में मैं निष्कर्ष है कि इस लक्ष्य को हासिल करना असंभव है पर आए हैं है। आरएक्स स्पेक के अनुसार एक पर्यवेक्षक ऑनरर कॉल करने के बाद जारी नहीं रह सकता है, ऑनरर के नाम के बाद अगला मूल्य प्राप्त करने के लिए आप कुछ भी नहीं कर सकते हैं। त्रुटि उत्पन्न होने से पहले मुझे कुछ तर्क डालने की आवश्यकता होगी। – bradgonesurfing

+1

सही। आपका प्रश्न आरएक्स स्पेक के साथ सीधे संघर्ष में है। यहां ध्यान दें कि व्यवहार व्यवहार नहीं है कि त्रुटियां, लेकिन प्रक्षेपण (ऑपरेटर का चयन करें), यह कि यह बहुत प्रासंगिक नहीं है। –

+0

मुझे एहसास हुआ है कि अगर मैं इस तरह की त्रुटियों का प्रचार करना चाहता हूं तो मुझे IObservable > जहां असाधारण को https://gist.github.com/bradphelan/6154972 जैसा परिभाषित किया गया है और अनिवार्य रूप से एक कंटेनर है जो अपवाद को पकड़ सकता है या एक मान – bradgonesurfing

उत्तर

2

प्रश्न के आधार पर गलत है, मैं Exceptional<T> मोनैड का उपयोग करके ऐसा करने के लिए better तरीका प्रस्तुत करता हूं। उदाहरण

IObservable<int> source = ....; 
IObservable<Exceptional<string>> withErrors = 
    source.Select(i=>Exceptional.Execute(()=>{ 
     if(v==2){ 
      throw new Exception("Ouch"); 
     } 
     return v.ToString(); 
    }); 


IObservable<Exception> errors = 
    withErrors.Where(v=>v.HasException).select(v=>v.Exception); 

IObservable<string> values = 
    withErrors.Where(v=>!v.HasException).select(v=>v.Value); 

के लिए और सिर्फ मनोरंजन के लिए आप

Exceptional<string> r = 
     from x in Exceptional.Execute(() => "xxx") 
     from y in Exceptional.Execute(() => "zzz") 
     select x + y; 

कर सकते हैं जो एक पीढ़ी होगा एक असाधारण मूल्य "xxxzzz" पकड़े। यदि कोई भी कदम अपवाद फेंकता है तो यह शॉर्ट सर्किट होगा और केवल अपवाद ही होगा।

मेरे कार्यान्वयन पर आधारित एक और तो जवाब https://gist.github.com/bradphelan/6154972

+0

हां, समस्या से निपटने का एक तरीका डेटा में अपवादों को बदलना है। एक और है कि उन्हें अपने कोड से बाहर निकलने के बिना अपवादों को पकड़ना और उनका उपभोग करना। दोनों योजनाएं आपको यह तय करने देती हैं कि अपवाद होने पर आपके कोड के कौन से हिस्से अनिश्चित हो रहे हैं। – Brandon

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