2014-05-16 12 views
6

मैं निम्नलिखित लिखने के लिए चाहते हैं , जो ठीक काम करता है, लेकिन शोध के अनुसार यह थ्रेड को अवरुद्ध कर देगा।टास्क दिया गया मान, टास्क <T> (async/इंतजार पैटर्न) के बिना

मैं इसके लिए async/प्रतीक्षा पैटर्न का उपयोग करना चाहता हूं लेकिन यह नहीं लगता कि यह कैसे करना है। अगर मैं async के साथ भी ऐसा ही किया/मेरे वर्तमान ज्ञान के साथ इंतजार है मैं हमेशा इस के साथ खत्म हो जाएगा:

public async Task<string> GetSomeValue() 
{ 
    //directly return the value of the Method 'DoSomeHeavyWork'... 
    var t = DoSomeHeavyWork(); 
    return await t; 
} 

public Task<string> DoSomeHeavyWork() 
{ 
    return Task.Run(() => { 
     // do some long working progress and return a string 
     return "Hello World!"; 
    }); 
} 

यह समाधान नहीं करता है काफी मेरी जरूरतों फिट क्योंकि मैं केवल स्ट्रिंग और नहीं एक Task<string> वापस करना चाहते हैं, कैसे क्या यह async/प्रतीक्षा के साथ हासिल किया जा सकता है?

+0

आप क्यों नहीं लौट सकते 'टास्क ' क्योंकि जब आप 'यह await' यह एक' स्ट्रिंग' देता है। क्या आप वह नहीं चाहते हैं? – Enigmativity

उत्तर

10

आप नहीं कर सकते।

async का पूरा बिंदु कोड असीमित रूप से चलाने के लिए है। तो कोड भविष्य मान का का वादा करता है, जो .NET में Task<string> के रूप में दर्शाया गया है।

इस तरह से इसके बारे में सोचो: अपने कोड समय से public string GetSomeValue() कहता है, तो अगर विधि रिटर्न, आप पहले से ही एक string है। परिभाषा के अनुसार यह तुल्यकालिक है।

आपके उदाहरण में, आपके पास "भारी" काम है जिसका अर्थ है "सीपीयू-बाध्य"। उस स्थिति में, बस सिंक्रनाइज़ कार्य करें:

public string DoSomeHeavyWork() 
{ 
    // do some long working progress and return a string 
    return "Hello World!"; 
} 

सामान्यतः, एपीआई को "झूठ" नहीं होना चाहिए; अगर वे तुल्यकालिक हैं, तो उनके पास एक तुल्यकालिक (गैर-Task-वापसी) हस्ताक्षर होना चाहिए।

संपादित करें: आपकी टिप्पणी के अनुसार, "भारी" काम एक डब्ल्यूसीएफ कॉल है, जो आई/ओ-बाउंड है, सीपीयू-बाध्य नहीं है।

उस स्थिति में, यह काम स्वाभाविक रूप से असीमित है। अतुल्यकालिक WCF विधियों (नहीं Task.Run) का उपयोग करें, और asynchrony अपने codebase के माध्यम से विकसित करने के लिए अनुमति देते हैं:

public async Task<string> GetSomeValueAsync() 
{ 
    //directly return the value of the Method 'DoSomeHeavyWork'... 
    var t = DoSomeHeavyWorkAsync(); 
    return await t; 
} 

public async Task<string> DoSomeHeavyWorkAsync() 
{ 
    // Call asynchronous WCF client. 
    await ...; 
    return "Hello World!"; 
} 
+0

'टास्क। रीसेट' संपत्ति के साथ, आप मेरी समस्या को कैसे हल करेंगे या आप कुछ बेहतर तरीके से जानते हैं? (यदि आप एक बेहतर विकल्प जानते हैं तो कोड स्निपेट के बारे में खुश रहें) –

+0

मेरे वास्तविक लाइव उदाहरण में मैं एक क्लाइंट को डब्लूसीएफ अनुरोध बुला रहा हूं, और क्लाइंट को अवरुद्ध करने के लिए एसिंक चलाने की विधि बनाना चाहता था, जबकि सर्वर विधि को कॉल कर रहा है (सर्वर/क्लाइंट दोनों WPF हैं) क्या मुझे हल की गई स्ट्रिंग/ऑब्जेक्ट के बजाय कार्य ऑब्जेक्ट को वापस करने से पहले चाहिए? –

+0

मैंने अपना पसंदीदा मेरे पसंदीदा समाधान के साथ संपादित किया है: बस काम सीधे करें। और मैंने इसे फिर से संपादित किया है क्योंकि "भारी" काम एक डब्ल्यूसीएफ अनुरोध है। –

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