2017-03-02 21 views
5

में एक गैर एसिंक-विधि (जो वेब कॉल करता है) को लपेटना मुझे पता है कि आपको केवल उन चीजों के लिए एसिंक का उपयोग करना चाहिए जो "सीपीयू-गहन" नहीं है, उदाहरण के लिए फाइल लिखती है, वेब कॉल इत्यादि। इसलिए मुझे यह भी पता है कि प्रत्येक विधि को Task.Run या कुछ समान में लपेटने का अर्थ नहीं है।एसिंक

हालांकि मुझे पता होना चाहिए कि जब कोई तरीका एक वेब कॉल करता है, लेकिन यह एसिंक इंटरफ़ेस प्रदान नहीं करता है। क्या यह इस मामले में लपेटने लायक है?

कंक्रीट उदाहरण:

मैं अपने WebAPI आवेदन (सर्वर) में CSOM (क्लाइंट SharePoint ऑब्जेक्ट मॉडल) का उपयोग कर रहा है और एक SharePoint सूची प्राप्त करना चाहते हैं।

यह सामान्य रूप से इस तरह से किया जाता है:

[HttpGet] 
[Route("foo/{webUrl}")] 
public int GetNumberOfLists(string webUrl) 
{ 
    using (ClientContext context = new ClientContext(webUrl)) 
    { 
     Web web = context.Web; 
     context.Load(web.Lists); 
     context.ExecuteQuery(); 

     return web.Lists.Count; 
    } 
} 

और मैं कुछ इस तरह करने के लिए इसे बदलने के बारे में सोचा:

[HttpGet] 
[Route("foo/{webUrl}")] 
public async Task<int> GetNumberOfLists(string webUrl) 
{ 
    using (ClientContext context = new ClientContext(webUrl)) 
    { 
     Web web = context.Web; 
     context.Load(web.Lists); 
     await Task.Run(() => clientContext.ExecuteQuery()); 

     return web.Lists.Count; 
    } 
} 

यह मतलब है और यह मदद करता है? जैसा कि मैं इसे समझता हूं, मैं सिर्फ क्वेरी ("ओवरहेड") निष्पादित करने के लिए एक नया धागा बना/चाहता हूं लेकिन कम से कम अनुरोध थ्रेड किसी अन्य अनुरोध के लिए स्वतंत्र/तैयार होगा (यह अच्छा होगा)।

लेकिन क्या यह इसके लायक है और इसे ऐसा किया जाना चाहिए?

यदि ऐसा है: क्या यह अजीब बात नहीं है कि माइक्रोसॉफ्ट बॉक्स के बाहर "async" विधि प्रदान नहीं करता है या क्या उन्हें इसकी परवाह नहीं है?

संपादित करें: टिप्पणी में सुझाए गए अनुसार Task.Run का उपयोग करने के लिए अपडेट किया गया।

+0

'टास्क.फैक्टरी.स्टार्टन्यू 'का उपयोग न करें,' टास्क.रुन 'का उपयोग करें। * SharePoint * को कॉल करने के लिए, संदर्भ में 'ExecuteQueryAsync' विधि है जिसे एक कार्य –

+0

वापस करने के लिए अनुकूलित किया जा सकता है मेरे पास मेरे CSOM लाइब्रेरी में' ExecuteQueryAsync' नहीं है जिसका उपयोग मैं कर रहा हूं .... दूसरी चीज़ जो मैंने बदल दी। –

+0

बस माइक्रोसॉफ्ट के माध्यम से 'माइक्रोसॉफ्ट.शेयरपॉइंटऑनलाइन.CSOM, 16.1.6216' तक पहुंचा - अभी भी' ExecuteQueryAsync' नहीं है। –

उत्तर

3

हालांकि मुझे पता होना चाहिए कि जब कोई तरीका वेब कॉल करता है, तो यह मुझे क्या करना चाहिए, लेकिन यह एसिंक इंटरफ़ेस प्रदान नहीं करता है।

दुर्भाग्य से अभी भी कुछ हद तक आम है। जैसे-जैसे विभिन्न पुस्तकालय अपने एपीआई अपडेट करते हैं, वे अंततः पकड़ लेंगे।

क्या यह इस मामले में लपेटने के लायक है?

हां, यदि आप यूआई थ्रेड से निपट रहे हैं। अन्यथा, नहीं।

कंक्रीट उदाहरण ... मेरी WebAPI आवेदन में (सर्वर)

फिर, नहीं, तुम नहीं Task.Run में रैप करने के लिए चाहते हैं। जैसा कि मेरे article on async ASP.NET में उल्लेख किया गया है:

आप कार्य का इंतजार करके कुछ पृष्ठभूमि कार्य बंद कर सकते हैं। रुन, लेकिन ऐसा करने में कोई बात नहीं है। वास्तव में, यह वास्तव में एएसपी.नेट थ्रेड पूल हेरिस्टिक के साथ हस्तक्षेप करके आपकी स्केलेबिलिटी को चोट पहुंचाएगा ...एक सामान्य नियम के रूप में, एएसपी.नेट पर थ्रेड पूल में काम कतारबद्ध न करें। Task.Run ASP.NET पर साथ

रैपिंग:

  • (अब एक धागा लेने और फिर इसे बाद में जारी करके) दो बार ASP.NET थ्रेड पूल heuristics हस्तक्षेप करता है।
  • ओवरहेड जोड़ता है (कोड को थ्रेड स्विच करना पड़ता है)।
  • धागे को मुक्त नहीं करता है (इस अनुरोध के लिए उपयोग किए गए धागे की कुल संख्या सिंक्रोनस संस्करण को कॉल करने के बराबर है)।

मैं यह समझ के रूप में, मैं सिर्फ बनाने/क्वेरी को निष्पादित ("भूमि के ऊपर") के लिए एक नया धागा की जरूरत है लेकिन कम से कम अनुरोध धागा मुक्त हो जाएगा/(कि अच्छा होगा) एक और अनुरोध के लिए तैयार ।

हां, लेकिन आप जो भी कर रहे हैं, वह बिना किसी लाभ के थ्रेड कूद रहा है। क्वेरी परिणाम पर अवरुद्ध करने के लिए प्रयुक्त धागा एक कम थ्रेड एएसपी.NET को अनुरोधों को संभालने के लिए उपयोग करना है, इसलिए किसी अन्य खपत से एक थ्रेड को मुक्त करना एक अच्छा व्यापार नहीं है।

क्या यह अजीब बात नहीं है कि माइक्रोसॉफ्ट बॉक्स के बाहर "async" विधि प्रदान नहीं करता है या क्या उन्हें इसकी परवाह नहीं है?

कुछ "पुराने" एमएस एपीआई अभी तक async संस्करणों को जोड़ने के लिए नहीं मिला है। वे निश्चित रूप से होना चाहिए, लेकिन डेवलपर समय एक सीमित संसाधन है।

+0

सही उत्तर कहते हैं, ठीक वही है जो मैं "ढूंढ रहा था" - धन्यवाद! –

0

यह आपकी समस्या का मेरा व्यक्तिगत दृष्टिकोण है और मेरे लिए उपरोक्त तरीके की आवश्यकता नहीं है। जब हम आईआईएस में अपना एपीआई होस्ट करते हैं, तो सर्वर सर्वर में मौजूद थ्रेड पूल से एक थ्रेड निर्दिष्ट करता है। आईआईएस में maxConcurrentRequestsPerCPU maxConcurrentThreadsPerCPU की एक सेटिंग भी है। आप इन मानों को अपने आप से अनुरोध को संभालने के बजाय अनुरोध को पूरा करने के लिए सेट कर सकते हैं।