2017-05-11 18 views
5

मैं लैम्ब्डा अभिव्यक्ति के अंदर एक एसिंक विधि को कॉल करना चाहता हूं। कृपया मेरी मदद नीचेलैम्ब्डा अभिव्यक्ति में Async Await जहां क्लॉज

जैसे कर -

return xyz.Where(async x=> await AsyncMethodCall(x.val)); 

और Async विधि लग रहा है

तरह
public async Task<bool> AsyncMethodCall(Data d){...} 

जब मैं ऊपर करते हैं, मैं निम्न त्रुटि

त्रुटि प्राप्त CS4010 प्रतिनिधि 'Func<Data, bool>' प्रतिनिधि के रूप में async lambda अभिव्यक्ति को परिवर्तित नहीं कर सकता है। एक async lambda अभिव्यक्ति void, Task या Task<T> लौटा सकती है, जिनमें से कोई भी 'Func<Data, bool>' में परिवर्तनीय नहीं है। मदद के लिए

धन्यवाद

+0

* फ़िल्टर * कहां है। यह * फिल्टर * चीजों को माना जाता है, यादृच्छिक परिवर्तन नहीं करते हैं। आप इसमें एक एसिंक्रोनस विधि का उपयोग क्यों कर रहे हैं? क्या आप इसका उपयोग कर रहे हैं जैसे कि यह * चयन * कथन था? –

+2

@PanagiotisKanavos उदाहरण के लिए यह एक वेब सेवा कॉल कर सकता है, या डीबी तक पहुंच सकता है ... सवाल अच्छा है ... आप इसे नहीं कर सकते हैं, और यहां तक ​​कि अगर आप शायद यह एक अच्छा विचार नहीं होगा, लेकिन वह एक और समस्या है ... – xanatos

+2

@xanatos तथ्य यह एक बुरा विचार है शायद आप ऐसा क्यों नहीं कर सकते हैं, यानी कोई 'कहां()' विधि क्यों नहीं है जो एक कार्य –

उत्तर

-2

तुम क्या कर रहे काम नहीं करेगा।

त्रुटि CS4010 कनवर्ट नहीं कर सकता async लैम्ब्डा अभिव्यक्ति को सौंपने के लिए प्रकार 'समारोह': कारण त्रुटि संदेश से स्पष्ट है। एक async lambda अभिव्यक्ति शून्य, कार्य या कार्य लौटा सकता है, जिनमें से कोई भी 'Func' में परिवर्तनीय नहीं है।

आपके पास एक लैम्ब्डा अभिव्यक्ति है जो Task<bool> से बाहर निकलती है। Where() फ़ंक्शन एक फ़ंक्शन प्रतिनिधि की अपेक्षा कर रहा है। आप कार्य को एक फ़ंक्शन प्रतिनिधि में परिवर्तित नहीं कर सकते हैं जिसका उपयोग bool प्राप्त करने के लिए किया जा सकता है। कहानी का अंत।

तुम सच में इस तरह से विधि कॉल करना चाहते हैं, तो आप यकीन है कि लैम्ब्डा एक bool async विधि करने के लिए कॉल के परिणाम देता है, इस मामले में, बनाने की जरूरत है:

return xyz.Where(x => AsyncMethodCall(x.val).Result); 

हो जाएगा ताकि काम करें और आपको सार्थक परिणाम दें क्योंकि परिणाम कॉलर को कॉल करने से विधि कॉल पूरा होने तक थ्रेड को अवरुद्ध कर दिया जाएगा।

6

असीमित अनुक्रम मुश्किल हैं क्योंकि आपको वास्तव में विशेष रूप से के बारे में सोचना है कि आप कोड करना चाहते हैं।

उदाहरण के लिए, आप क्रमिक रूप से AsyncMethodCall कॉल पर अमल करें, और उसके सभी परिणामों को वापस करना चाहते हो सकता है:

var result = new List<T>(); 
foreach (var d in xyz) 
    if (await AsyncMethodCall(d.val)) 
    result.Add(d); 
return result; 

या, आप सभी AsyncMethodCall कॉल समवर्ती पर अमल कर सकता है, और फिर इकट्ठा करने और परिणाम वापस (फिर से, सभी को एक बार):

var tasks = xyz.Select(async d => new { d, filter = await AsyncMethodCall(d.val) }); 
var results = await Task.WhenAll(tasks); 
return results.Where(x => x.filter).Select(x => x.d); 

या, आप सभी AsyncMethodCall कॉल क्रमिक रूप से निष्पादित, और एक समय में परिणाम एक उत्पादन कर सकता है। यह दृष्टिकोण IEnumerable<T> के साथ असंगत है (मान लीजिए कि आप कॉल को एसिंक्रोनस रखना चाहते हैं)। यदि आप एक अनुक्रम बनाना चाहते हैं जहां AsyncMethodCall अनुक्रमिक गणना के दौरान अतुल्यकालिक रूप से लागू किया गया है, तो आपको IAsyncEnumerable<T> में बदलना होगा।यदि आप उपभोक्ता द्वारा शुरू करने के अनुक्रम का उत्पादन करना चाहते हैं और उसके बाद परिणाम स्वयं उत्पन्न करते हैं, तो आपको IObservable<T> में बदलना होगा।

या, आप एक साथ में सभी AsyncMethodCall कॉल निष्पादित कर सकते हैं, और परिणाम एक समय में उत्पन्न कर सकते हैं। यह IEnumerable<T> के साथ भी असंगत है; आपको IObservable<T> में बदलना होगा। और आपको यह तय करने की भी आवश्यकता होगी कि मूल क्रम को बनाए रखना है या AsyncMethodCall पूरा करने के लिए उन्हें उत्पादन करना है या नहीं।

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