2015-05-22 20 views
8

से सिंक्रनाइज़ रूप से सीपीयू-बाध्य विधियों को कॉल करने के बारे में भ्रम। मैं अपने पैरों को .NET 4.5 के async/प्रतीक्षा निर्माण के साथ गीला कर रहा हूं। मैं एक विश्वसनीय वेब एपीआई समाधान पर काम कर रहा हूं। मैं यह पता लगाने की कोशिश कर रहा हूं कि सीपीयू-बाध्य ऑपरेशन के साथ क्या करना है - 1) इसे वर्तमान थ्रेड से सिंक्रनाइज़ रूप से कॉल करें, या 2) Task.Run() का उपयोग करें?एक एसिंक विधि

के इस page से उदाहरण का उपयोग करते हैं:

async Task<int> AccessTheWebAsync() 
{ 
    // You need to add a reference to System.Net.Http to declare client. 
    HttpClient client = new HttpClient(); 

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents). 
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); 

    // You can do work here that doesn't rely on the string from GetStringAsync. 
    DoCPUBoundWork(); 

    // The await operator suspends AccessTheWebAsync. 
    // - AccessTheWebAsync can't continue until getStringTask is complete. 
    // - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    // - Control resumes here when getStringTask is complete. 
    // - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask; 

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length; 
} 

यहाँ, मान लेते हैं DoCPUBoundWork() सख्ती से सीपीयू बाध्य है और किसी भी तरह का कोई आईओ शामिल हैं।

क्या यह वर्तमान धागे से इसे दिखाने के लिए सबसे अच्छा अभ्यास है?

या क्या यह निम्नलिखित है?

await Task.Run(() => DoCPUBoundWork()).ConfigureAwait(false); 

मैंने श्री क्लेरी के कुछ पदों पर पढ़ा है, और कुछ मिश्रित सुझाव प्राप्त कर रहे हैं। इस post में, वह सुझाव देता है कि async/await/Task.Run() के अनावश्यक ओवरहेड से बचने के लिए सीपीयू-बाध्य सामग्री को सिंक्रनाइज़ करना बेहतर है। हालांकि, इस post में, वह किसी भी अपवाद मामलों का उल्लेख किए बिना CPU-bound संचालन के लिए Task.Run() का उपयोग करने का सुझाव देता है। मुझे यकीन है कि मुझे कुछ याद आ रही है। इस पर कुछ स्पष्टीकरण प्राप्त करने की उम्मीद है।

+0

आपका DoIndependentWork आमतौर पर कितने समय तक चलता है? –

+0

मान लें कि उच्च लोड के तहत समस्याओं का कारण बनने में काफी समय लगता है ... – Zoomzoom

उत्तर

6

क्या यह वर्तमान धागे से इसे दिखाने के लिए सबसे अच्छा अभ्यास है?

यदि आपका वर्तमान थ्रेड मुक्त है, तो एसिंक ऑपरेटिंग चल रहा है, तो एक अलग थ्रेड का उपयोग क्यों करें? क्या थ्रेड आपके द्वारा पहले से उपयोग किए जा रहे से बेहतर होगा?

प्रश्न DoIndependentWork वास्तव में क्या कर रहा है इसके बारे में दिमाग में आता है। यदि यह महत्वपूर्ण है कि HTTP अनुरोध समाप्त होने से पहले यह पूरा हो जाए, तो मैं इसे सिंक्रनाइज़ कर दूंगा। यदि HTTP अनुरोध पूरा होने से पहले पूरा करने के लिए काम महत्वपूर्ण नहीं है, तो मैं एक पूरी तरह से अलग समाधान की तलाश में हूं। Task.Run का उपयोग एएसपी.नेट में खतरनाक है।

याद रखें कि एएसपी.नेट में निरंतरता थ्रेड पूल थ्रेड पर चल रही है।

+0

तो ... टास्क.रुन() का उपयोग करके इसे किसी अन्य थ्रेड पर ऑफ़लोड करने का अर्थ कब होता है? (मुझे उलझन में है क्यों स्टीफन क्लेरी अपने ब्लॉग में सीपीयू-बाउंड सामान के लिए टास्क.रुन() का उपयोग करने का सुझाव देता है) – Zoomzoom

+0

wpf में ui-bound * threads * के बारे में क्या? गुई को अवरुद्ध करने से बचने के लिए एक अतिरिक्त कार्य की गोलीबारी संभव होगी ... –

+2

@ एंड्रियास आप सही हैं, अगर यह डब्ल्यूपीएफ था तो मैं अलग-अलग सलाह दूंगा। लेकिन यह एएसपी.नेट है, जो अलग है। –

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