2011-11-09 7 views
8

मैं एक एसिंक्रोनस सेवा लागू कर रहा हूं। माइक्रोसॉफ्ट के example का मूल्यांकन करने के बाद, मैं सोच रहा हूं कि उनका दृष्टिकोण वास्तव में असीमित है या नहीं। मुझे पूरा यकीन है कि यह है, लेकिन कुछ नमूने मैंने ऑनलाइन देखा है और AsyncCallback पैरामीटर मुझे आश्चर्यचकित करता है।सचमुच एसिंक्रोनस डब्ल्यूसीएफ सेवा

public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) 
{ 
    // Starts synchronous task 
    var acmeAsyncResult = new AcmeAsyncResult<Anvil> 
    { 
    Data = new Anvil() 
    };  
    return acmeAsyncResult; 
} 

public Anvil EndGetAcmeAnvil(IAsyncResult result) 
{ 
    var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; 

    return acmeAsyncResult != null 
    ? acmeAsyncResult.Data 
    : new Anvil(); 
} 

सुंदर सरल है, लेकिन कारण है कि हम एक AsyncCallback पैरामीटर की क्या ज़रूरत है:

उदाहरण के अनुसार, हम लागू करने के लिए शुरू और इस तरह समाप्ति विधि जोड़ी की जरूरत है? क्या हमें callback पर कॉल नहीं करना चाहिए जो बदले में अंत विधि को ट्रिगर करेगा?

यह मेरे मन में है:

public delegate void AsyncMethodCaller(AcmeAsyncResult<Anvil> acmeAsyncResult, 
             AsyncCallback callback); 

public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) 
{ 
    var acmeAsyncResult = new AcmeAsyncResult<Anvil>(); 
    var asyncMethodCaller = new AsyncMethodCaller(GetAnvilAsync); 

    // Starts asynchronous task 
    asyncMethodCaller.BeginInvoke(acmeAsyncResult, callback, null, null); 

    return acmeAsyncResult; 
} 

private void GetAcmeAnvilAsync(AcmeAsyncResult<Anvil> acmeAsyncResult, 
           AsyncCallback callback) 
{ 
    acmeAsyncResult.Data = new Anvil(); 
    callback(acmeAsyncResult); // Triggers EndGetAcmeAnvil 
} 

public Anvil EndGetAcmeAnvil(IAsyncResult result) 
{ 
    var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; 

    return acmeAsyncResult != null 
    ? acmeAsyncResult.Data 
    : new Anvil(); 
} 

मैं loadUI का उपयोग कर कुछ भार परीक्षण किया था, लेकिन कोई स्पष्ट प्रदर्शन में परिवर्तन नहीं थी।

उत्तर

5

मुझे good article मिला जो आपके असिनक डब्ल्यूसीएफ सेवा से सर्वश्रेष्ठ प्रदर्शन कैसे प्राप्त करें।

सार है:

  1. में भारी काम नहीं करते विधि शुरू, और
  2. कॉलबैक समाप्ति विधि को गति प्रदान करने करते हैं।

यहाँ पाठ से एक उद्धरण है:

सर्वश्रेष्ठ प्रदर्शन के लिए, यहाँ दो सिद्धांतों जब आप कॉल/लागू ऊपर अतुल्यकालिक पैटर्न हैं:

  • सिद्धांत 1:के अंदर भारी भारित काम न करें विधि शुरू करें ...

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

  • सिद्धांत 2: बचें समाप्ति के एक ही धागे पर विधि बुला विधि शुरू करो।

    अंत विधि सामान्य रूप से अवरुद्ध होती है। यह ऑपरेशन पूरा करने के लिए इंतजार कर रहा है। यदि आप एंड विधि को लागू करते हैं, तो आप देखेंगे कि यह वास्तव में IAsyncResult.WaitHandle.WaitOne() पर कॉल करता है। दूसरी तरफ, सामान्य कार्यान्वयन के रूप में, यह वेटहैंडलमैन्युअल रीसेट इवेंट आवंटित विलंब है। जब तक आप इसे कॉल नहीं करते हैं, तब तक इसे आवंटित नहीं किया जाएगा। तेजी से संचालन के लिए, यह बहुत सस्ता है। हालांकि, एक बार अंत कहा जाता है, तो आपको इसे आवंटित करना होगा। पर कॉल करने के लिए सही जगह ऑपरेशन के कॉलबैक से है। जब कॉलबैक का आह्वान किया जाता है, तो इसका मतलब है कि अवरुद्ध कार्य वास्तव में पूरा हो गया है। इस बिंदु पर, आप प्रदर्शन को बलि किए बिना डेटा पुनर्प्राप्त करने के लिए एंड पर कॉल कर सकते हैं।

2

मुझे लगता है कि इसका मुख्य कारण इस तरह से अलग है कि डब्लूसीएफ रनटाइम थ्रेड सिंक्रनाइज़ेशन को संभालने वाला है क्योंकि आप इसे मैन्युअल रूप से संभालने के विरोध में हैं।

यदि आप कॉलबैक के माध्यम से अंतिम विधि का आह्वान कर रहे थे, तो आपको सिंक्रनाइज़ेशन को संभालना होगा जो पैटर्न को थोड़ा अधिक जटिल बनाता है (जैसा कि आप अपने कोडिंग उदाहरणों में देख सकते हैं)। इस पैटर्न का लक्ष्य आपके लिए थ्रेडिंग सामानों के बारे में वास्तव में अवगत नहीं है, आप थ्रेडिंग के कार्यान्वयन विवरण के बारे में सोचने के बिना अपने लंबे समय तक चलने वाले ऑपरेशन को कोड करना चाहते हैं।

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