2008-10-23 11 views
14

मैं एक webservice विधि में कुछ async सामान करने की कोशिश कर रहा हूँ। मान लें कि मेरे पास निम्न API कॉल है: http://www.example.com/api.asmx.NET वेब सेवा और पृष्ठभूमिवर्कर धागे

और विधि GetProducts() कहा जाता है।

मैं यह GetProducts विधियों, मैं कुछ सामान (उदाहरण के लिए डेटाबेस से डेटा प्राप्त करें) तो परिणाम देने से ठीक पहले, मैं कुछ async सामान करना चाहता हूं (उदाहरण के लिए मुझे एक ईमेल भेजें)।

तो मैंने यही किया।

[WebMethod(Description = "Bal blah blah.")] 
public IList<Product> GetProducts() 
{ 
    // Blah blah blah .. 
    // Get data from DB .. hi DB! 
    // var myData = ....... 
    // Moar clbuttic blahs :) (yes, google for clbuttic if you don't know what that is) 

    // Ok .. now send me an email for no particular reason, but to prove that async stuff works. 
    var myObject = new MyObject(); 
    myObject.SendDataAsync(); 

    // Ok, now return the result. 
    return myData; 
    } 
} 

public class TrackingCode 
{ 
    public void SendDataAsync() 
    { 
     var backgroundWorker = new BackgroundWorker(); 
     backgroundWorker.DoWork += BackgroundWorker_DoWork; 
     backgroundWorker.RunWorkerAsync(); 
     //System.Threading.Thread.Sleep(1000 * 20); 
    } 

    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     SendEmail(); 
    } 
} 

अब, जब मैं इस कोड को चलाता हूं तो ईमेल कभी नहीं भेजा जाता है। अगर मैं थ्रेड से बाहर निकलता हूं। सो जाओ .. फिर ईमेल भेजा जाता है।

तो ... पृष्ठभूमि कार्यकर्ता धागा टूट गया क्यों है? क्या यह मूल धागे पर निर्भर है? क्या यह गलत तरीका है कि मुझे एएसपीनेट वेब ऐप में पृष्ठभूमि या फोर्कड थ्रेडिंग करना चाहिए?

उत्तर

17

BackgroundWorker उपयोगी है जब आपको वापस UI (थ्रेड) को सिंक्रनाइज़ करने की आवश्यकता होती है, उदाहरण के लिए एफ़िनिटी कारणों के लिए। इस मामले में, ऐसा लगता है कि बस ThreadPool का उपयोग पर्याप्त (और अधिक सरल) से अधिक होगा। आप उच्च मात्रा है, तो एक निर्माता/उपभोक्ता कतार बेहतर थ्रॉटलिंग अनुमति दे सकता है (ताकि आप धागे में डूब नहीं है) - लेकिन मुझे लगता है ThreadPool यहाँ ठीक हो जाएगा ...

public void SendDataAsync() 
{ 
    ThreadPool.QueueUserWorkItem(delegate 
    { 
     SendEmail(); 
    }); 
} 

इसके अलावा - मैं कर रहा हूँ पूरी तरह से यकीन नहीं है कि आप सोते हुए क्या हासिल करना चाहते हैं? यह सिर्फ एक धागा बांध देगा (सीपीयू का उपयोग नहीं कर रहा है, लेकिन कोई अच्छा नहीं कर रहा है)। विस्तृत करने के लिए परवाह? यह दिखता है जैसे आप अपने वास्तविक वेब पेज को रोक रहे हैं (यानी नींद वेब पेज थ्रेड पर होती है, ई-मेल थ्रेड नहीं)। आप यहाँ क्या करने की कोशिश कर रहे हैं?

* वास्तव में, यह प्रयोग करेंगे जो कुछ भी सिंक-प्रसंग, BackgroundWorker उदाहरण कचरा एकत्र किया जा सकता है कि क्योंकि इसमें कोई संदर्भ (क्षेत्र से बाहर चला गया है) जगह

+0

नींद की टिप्पणी की गई है। मैंने यह देखा कि मैं एक ईमेल भेज सकता हूं या नहीं। जब नींद को अनुमोदित किया जाता है, तो पृष्ठभूमि कार्यकर्ता धागा कोड निष्पादित किया जाता है। जब कोड को कम किया जाता है, तो पृष्ठभूमि कार्यकर्ता थ्रेड कोड कभी निष्पादित नहीं होता है। मैं इसके बजाय थ्रेडपूल का उपयोग करने का प्रयास करूंगा। –

+0

> * यदि आपके पास उच्च मात्रा है, तो एक निर्माता/उपभोक्ता कतार बेहतर थ्रॉटलिंग की अनुमति दे सकती है (इसलिए आप धागे में डूब नहीं जाते हैं) * ooooooo !!!मुझे खुशी है कि आपने वास्तव में इस बिंदु को उठाया! वेब सेवा विधि वास्तव में उच्च मात्रा है! भी मायने रखती है वास्तव में दिलचस्प बनाने के लिए, यह वास्तव में एक ई-मेल नहीं भेज रहा है, लेकिन वास्तव में एक और बाहरी वेबसाइट (EKK, मत पूछो) मार ... ताकि आप मैं इस निर्माता/उपभोक्ता कतार thingy कर सुझाव है? यदि हां ... क्या यह संदर्भ देने के लिए एक अच्छा पृष्ठ है? http://www.albahari.com/threading/part4.aspx (कृपया कोड + के लिए एक उचित बिट नीचे स्क्रॉल करें)। विचार? –

+0

@Marc Gravell मैं अपने समाधान का उपयोग कर की कोशिश की है, लेकिन मैं सिर्फ कारण है कि यह कार्य पूरा करने के लिए बहुत अधिक समय लेने के लिए सोच रहा हूँ। – AnandMohanAwasthi

0

यह 20 क्योंकि कुछ सेकंड बाद ही तोड़ सकता है में है =।

+0

ध्यान दें कि नींद() वेब पेज धागे पर है; यह अधिक संभावना है कि BackgroundWorker एक सिंक संदर्भ है कि नींद से अवरुद्ध किया जा रहा उपयोग करने के लिए कोशिश कर रही है() अपने आप में –

1

पुन उत्पादक/उपभोक्ता; मूल रूप से - यह कुछ प्रकार की थ्रॉटल रखने के लायक है। सबसे सरल स्तर पर, Semaphore का उपयोग ज्ञात मात्रा में काम करने के लिए (थ्रेड पूल को संतृप्त करने से बचने के लिए) नियमित रूप से ThreadPool के साथ) का उपयोग किया जा सकता है; लेकिन एक निर्माता/उपभोक्ता कतार शायद अधिक कुशल और प्रबंधित होगा।

जॉन स्कीट में ऐसी कतार here (CustomThreadPool) है। यदि आप चाहें तो शायद इसके बारे में कुछ नोट्स लिख सकते हैं।

यह कहा गया: यदि आप किसी बाहरी वेब साइट पर कॉल कर रहे हैं, तो यह संभावना है कि आपके पास नेटवर्क IO/समापन बंदरगाहों पर बहुत अधिक इंतजार होगा; इस प्रकार, आपके पास थ्रेड की थोड़ी अधिक संख्या हो सकती है ... जाहिर है (इसके विपरीत) यदि काम सीपीयू-बाउंड था, तो आपके पास CPU कोर की तुलना में अधिक थ्रेड होने की कोई बात नहीं है।