2014-04-25 9 views
20

मैं एक एसिटर्रोन फ़ंक्शन को लागू करने की कोशिश कर रहा हूं जो एक इटरेटर लौटाता है।असिंक्रोनस इटेटरेटर कार्य <IENumerable <T>>

private async Task<IEnumerable<char>> TestAsync(string testString) 
    { 
     foreach (char c in testString.ToCharArray()) 
     { 
      // do other work 
      yield return c; 
     } 
    } 

हालांकि, वहाँ एक त्रुटि संदेश है कि समारोह पुनरावर्तक ब्लॉक नहीं किया जा सकता क्योंकि Task<IEnumerable<char>> पुनरावर्तक इंटरफ़ेस प्रकार नहीं है: विचार इस प्रकार है। क्या कोई समाधान है?

+4

ध्यान दें कि यह केवल इतना कहता है कि * पहली जगह में गणना करने योग्य * एसिंक है - यह इसे एसिंक एन्युमरेटर का कोई भी प्रकार नहीं बनाता है। क्या वास्तव में आप करना चाहते हैं? क्योंकि मुझे संदेह है कि यह इसे प्राप्त नहीं करेगा। –

+3

जांचें http://asyncenum.codeplex.com/ – daryal

+0

मैं इस फ़ंक्शन को वर्कर थ्रेड पर स्ट्रीम के साथ काम करने के लिए चलाने और UI थ्रेड पर प्रतीक्षा परिणाम का उपभोग करना चाहता हूं। – user2341923

उत्तर

13

ऐसा लगता है कि आप वास्तव में क्या देख रहे हैं IObservable<T>, जो पुश-आधारित एसिंक्रोनस IEnumerable<T> जैसा है। माइक्रोसॉफ्ट ओपन टेक्नोलॉजीज (अपाचे-2.0 के तहत लाइसेंस प्राप्त कोड) (कोई संबद्धता) से IObservable<T> के साथ काम करने के लिए LINQ-to-Objects और अधिक जैसे काम करने के लिए देखें।

IEnumerable<T> के साथ समस्या यह है कि वास्तव में यह नहीं है कि वास्तव में गणना स्वयं को असंकालिक बनाती है। आप आरएक्स पर निर्भरता को जोड़ने के लिए (जो वास्तव में क्या IObservable<T> बेहतर बनाता है) नहीं करना चाहते हैं, इस विकल्प आप के लिए काम कर सकते हैं:

public async Task<IEnumerable<char>> TestAsync(string testString) 
{ 
    return GetChars(testString); 
} 

private static IEnumerable<char> GetChars(string testString) 
{ 
    foreach (char c in testString.ToCharArray()) 
    { 
     // do other work 
     yield return c; 
    } 
} 

हालांकि मैं बाहर बात करने के लिए है कि क्या वास्तव में है जानने के बिना करना चाहते हैं असीमित रूप से किया जा रहा है, आपके लक्ष्यों को पूरा करने के लिए एक बेहतर तरीका हो सकता है। आपके द्वारा पोस्ट किए गए कोड में से कोई भी वास्तव में असीमित रूप से कुछ भी नहीं करेगा, और मुझे वास्तव में पता नहीं है कि // do other work में कुछ भी अतुल्यकालिक है (इस स्थिति में, यह आपकी अंतर्निहित समस्या का समाधान नहीं है हालांकि यह आपके कोड को संकलित करेगा)।

9

पिछले उत्तरों पर विस्तृत करने के लिए, आप वही करने के लिए रीएक्टिव एक्सटेंशंस 'Observable.Create<TResult> विधियों के परिवार का उपयोग कर सकते हैं।

यहाँ एक उदाहरण है:

var observable = Observable.Create<char>(async (observer, cancel) => 
{ 
    for (var i = 0; !cancel.IsCancellationRequested && i < 100; i++) 
    { 
     observer.OnNext(await GetCharAsync()); 
    } 
}); 

का तरीका यहां बताया LINQPad में उपयोग कर सकते हैं, उदाहरण के लिए है:

// Create a disposable that keeps the query running. 
// This is necessary, since the observable is 100% async. 
var end = Util.KeepRunning(); 

observable.Subscribe(
    c => Console.WriteLine(c.ToString()), 
    () => end.Dispose()); 
2

बात इस तरह के A more "batteries-included" implementation, भाषा समर्थन सहित, वर्तमान में (कम से है लिखने का समय) 0 #सी # 8.0 में शामिल करने के लिए।

जैसा कि मैं इसे समझता हूं, यह किसी भी समय परिवर्तन के अधीन है।

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