2012-07-13 17 views
7

असिंक्रोनस प्रतिनिधि (कॉलबैक) के साथ थ्रेड (थ्रेडपूल थ्रेड नहीं) को बदलना।एसिंक्रोनस प्रतिनिधि बनाम थ्रेड

मेरा परिदृश्य: एक थ्रेड/del.beginInvoke() प्रति ग्राहक स्पॉन करें।

मेरे अनुसार,

कारण

  1. कॉलबैक/कॉल प्रतिनिधि के माध्यम से अधिसूचना के लिए फिर से जरूरत कॉलबैक में
  2. बचें थ्रेड ओवरहेड, (प्रतिनिधियों ThreadPool धागे का उपयोग करें)
  3. पासिंग तर्क (बचें ऑब्जेक्ट कास्टिंग) और विधि से वापसी मूल्य की आवश्यकता है।

यदि ऊपर दिए गए कारण गलत हैं तो मुझे सही करें।

  1. क्या कोई अन्य कारण है?
  2. असिंक्रोनस डेलीगेट्स के साथ मुझे कुछ सामान करने की ज़रूरत है कि धागे नहीं कर सकते हैं?
    3. प्रदर्शन?

उदाहरण

public delegate void SendCallbackType(); 

    SendCallbackType senderdel= new SendCallbackType(SendData); 

    public void StartSend() // This method Could be Called more than 700 times (Thread per Client) 
    { 
     senderdel.BeginInvoke(SendCallback,null); 
        // (or) 
     Thread t = new Thread(new ThreadStart(ThreadSend)); 
     t.IsBackground = true; 
     t.Start(); 
    } 

    //Async Delegate 
    void SendData() 
    { 
     string data = QueData.DeQueue(); 
     RaiseOnData(data); // Raise to event. 
    } 
    void SendCallback(IAsyncResult ar) 
    { 
     senderdel.BeginInvoke(SendCallback, null); 
    } 

//Thread 
    void ThreadSend() 
    { 
     while (true) 
     { 
     string data = QueData.DeQueue(); 
     RaiseOnData(data); // Raise to event. 
     } 
    } 

ऊपर कौन सा विकल्प सबसे अच्छा होगा से। प्रदर्शन ?

उत्तर

10

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

असिंक प्रतिनिधि सीपीयू गहन कार्यों के लिए ठीक हैं। I/O गहन कार्यों (जैसे स्ट्रीम, डेटाबेस कॉल और वेब सेवा कॉल पढ़ने के लिए) के लिए आपको प्रारंभिक कक्षाओं (स्ट्रीम, एसक्यूएलकनेक्शन, वेब क्लाइंट, ...) द्वारा सीधे शुरू की गई BeginXXX, EndXXX विधियों का उपयोग करना चाहिए। इस तरह आप लंबे I/O ऑपरेशन के दौरान किसी भी थ्रेड का उपयोग नहीं कर रहे हैं। आप I/O Completion Ports का उपयोग कर रहे हैं जो I/O बाध्य कार्यों के मामले में सबसे अच्छी बात है। यह किसी भी धागे और धागे के पूल की तुलना में परिमाण के अधिक प्रदर्शन और संसाधन सस्ता होगा।

तो संक्षेप में प्रस्तुत करने के लिए:

  • आई/ओ गहन कार्यों के लिए मैं/हे समापन बंदरगाहों का उपयोग करें। यदि I/O गहन कार्य एक खराब लिखित पुस्तकालय के अंदर लपेटा गया है जो इस संभावना की पेशकश नहीं करता है तो टीईपी का उपयोग करें जो .NET 4.0 में पेश किया गया था।
  • सीपीयू गहन कार्यों के लिए टीईपी का उपयोग करें जो .NET 4.0 में पेश किया गया था।

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

सामान्य तौर पर यह अच्छा TPL का उपयोग शुरू और कार्यों के रूप में अपने तरीके से समन्वित ताकि आप .NET 4.5 जो async परिचय के लिए तैयार कर रहे हैं करने के लिए अभ्यास है/कीवर्ड्स का इंतजार है।

+0

@ डारिन: उत्तर के लिए धन्यवाद।यहां मामला विंडोज़ एप्लीकेशन है, मुझे लगता है कि पूरी तरह से सीपीयू गहन कार्य, 1000 धागे बनाम 1000 del.begininvoke() कॉल –

+0

@MSK पर प्रदर्शन के दौरान प्रदर्शन के बारे में क्या है, निश्चित रूप से इस मामले में टीपीएल के साथ जाएं और यदि आप पुराने संस्करण का उपयोग कर रहे हैं। नेट थ्रेड पूल (थ्रेडपूल, पृष्ठभूमिवर्कर, असिंक प्रतिनिधि, ... => का उपयोग करते हैं, वे सभी थ्रेडपूल पर वैसे भी समाप्त हो जाएंगे)। इस स्थिति में मैन्युअल रूप से धागे को मत बढ़ाओ। –

+0

@ डारिन: और मुझे आग की जरूरत नहीं है और भूल जाओ। यहां मुझे डेक्यू (थ्रेडपूल के बावजूद) के लिए समर्पित थ्रेड की आवश्यकता है और साथ ही यह लंबी चल रही प्रक्रिया है। –