क्या मैं IIS पर लंबे समय से चल रही नौकरियों को पूरा करने के लिए थ्रेड्स का उपयोग कर सकता हूं?


85

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

मुझे नहीं पता कि क्या आईआईएस मेरे धागे को चालू रखने की अनुमति देता है, भले ही उपयोगकर्ता सत्र समाप्त हो जाए। कल्पना कीजिए, उपयोगकर्ता घटना को आग लगाता है और हम सर्वर पर ऑब्जेक्ट को त्वरित करते हैं और एक नए थ्रेड में विधि को आग लगाते हैं। उपयोगकर्ता "आपका अनुरोध सबमिट किया गया है" संदेश से खुश है और अपने ब्राउज़र को बंद कर देता है। आखिरकार, यह उपयोगकर्ता सत्र IIS पर टाइम आउट हो जाएगा, लेकिन थ्रेड अभी भी चल रहा है, काम कर सकता है। क्या IIS थ्रेड को चालू रखने की अनुमति देगा या क्या उपयोगकर्ता सत्र समाप्त होने के बाद यह इसे मार देगा और ऑब्जेक्ट का निपटान करेगा?

संपादित करें: उत्तर और टिप्पणियों से, मैं समझता हूं कि ऐसा करने का सबसे अच्छा तरीका IIS के बाहर लंबे समय से चल रहे प्रसंस्करण को स्थानांतरित करना है। बाकी सब चीजों के अलावा, यह एपिडोमाइन रीसाइक्लिंग समस्या से निपटता है। व्यवहार में, मुझे सीमित समय में जमीन से संस्करण 1 प्राप्त करने की आवश्यकता है और एक मौजूदा ढांचे के अंदर काम करना है, इसलिए सेवा परत से बचना चाहते हैं, इसलिए IIS के अंदर धागे को बंद करने की इच्छा है। व्यवहार में, "लंबे समय से चल रहा है" यहां केवल कुछ मिनट होंगे और वेबसाइट पर संक्षिप्तता कम होगी इसलिए यह ठीक होना चाहिए। लेकिन, अगले संस्करण में निश्चित रूप से एक अलग सेवा परत में विभाजन की आवश्यकता होगी।


1
क्या आपके पास कोई और विवरण है जिसे संसाधित करने और आपके होस्टिंग वातावरण की आवश्यकता है? उदाहरण के लिए, क्या आप एक सेवा स्थापित करने में सक्षम हैं?
सीनो

आप हमेशा Async और Await प्रोग्रामिंग विधियों (Visual Studio 2012+) का उपयोग कर सकते हैं । स्वयं को प्रबंधित करने की तुलना में बहुत अधिक क्लीनर।
सॉसेजफिंगर

जवाबों:


65

आप जो चाहते हैं उसे पूरा कर सकते हैं, लेकिन यह आमतौर पर एक बुरा विचार है। कई ASP.NET ब्लॉग और CMS इंजन इस दृष्टिकोण को लेते हैं, क्योंकि वे एक साझा होस्टिंग सिस्टम पर इंस्टॉल करने योग्य होना चाहते हैं और एक विंडोज़ सेवा पर निर्भरता नहीं लेना चाहते हैं जिसे इंस्टॉल करने की आवश्यकता है। आमतौर पर वे Global.asax में एक लंबे समय तक चलने वाले थ्रेड को किक करते हैं, जब ऐप शुरू होता है, और उस थ्रेड प्रक्रिया को कार्यों को कतारबद्ध किया जाता है।

अनुरोधों को संसाधित करने के लिए IIS / ASP.NET के लिए उपलब्ध संसाधनों को कम करने के अलावा, आपके पास थ्रेड के साथ समस्याएँ भी हैं जब AppDomain को पुनर्नवीनीकरण किया जाता है, और फिर आपको फ्लाइट के दौरान कार्य की दृढ़ता से निपटना पड़ता है, जैसा कि इन-फ्लाइट, जब AppDomain बैक अप आता है तो काम शुरू करने के साथ-साथ।

ध्यान रखें कि कई मामलों में AppDomain एक डिफ़ॉल्ट अंतराल पर स्वचालित रूप से पुनर्नवीनीकरण किया जाता है, साथ ही अगर आप web.config, आदि को अपडेट करते हैं।

यदि आप किसी भी समय अपने धागे की दृढ़ता और लेन-देन के पहलुओं को मार सकते हैं, तो आप कुछ बाहरी प्रक्रिया से AppDomain रीसाइक्लिंग के आसपास प्राप्त कर सकते हैं जो आपकी साइट पर कुछ अंतराल पर अनुरोध करता है - ताकि यदि साइट आपको पुनर्नवीनीकरण कर सके इसकी गारंटी दी जाती है कि यह X मिनट के भीतर अपने आप फिर से शुरू हो जाए।

फिर, यह आमतौर पर एक बुरा विचार है।

संपादित करें: यहां इस तकनीक के कुछ उदाहरण दिए गए हैं:

सामुदायिक सर्वर: अनुसूचित सेवाओं में रन कोड के लिए विंडोज सेवाओं बनाम बैकग्राउंड थ्रेड का उपयोग करना जब वेबसाइट पहले शुरू होती है तो बैकग्राउंड थ्रेड बनाना

EDIT (दूर के भविष्य से) - इन दिनों मैं Hangfire का उपयोग करूंगा


1
धन्यवाद, यह व्यावहारिक है। पुनर्नवीनीकरण एक निश्चित हत्यारा है और मैं उससे कहता हूं जो आप कह रहे हैं कि मैं इसे कठिन-व्रत के रूप में कर सकता हूं लेकिन यह खतरनाक है।
Frans

हाँ, यहाँ की जाँच करें: professionalaspnet.com/archive/2007/09/02/... और यहाँ के बारे में कैसे समुदाय सर्वर एक ही बात को संभालती है एक धागा है: dev.communityserver.com/forums/t/459942.aspx
ब्रायन Batchelder

मेरे मामले में, मैं केवल IIS को कभी भी रीसायकल नहीं करने और साइट को कभी भी बेकार नहीं करने में सक्षम था। इसने इसे ऐसा बनाया कि मैं इस धारणा के तहत काम करने में सक्षम था और यह कि केवल तैनाती के समय और पुनर्नवीनीकरण किए जाने के दौरान साइट को पुनर्नवीनीकरण किया जाएगा। चूंकि मैं सिर्फ एक एडमिन टाइप साइट कर रहा था, इसलिए यह मेरे लिए एकदम सही था।
ब्रेट करें

1
विचित्र कि यह बहुत सारे upvotes है। यह बात संभव है कि ASP.NET के बारे में बहुत ही शांत चीजों में से एक है: कि सभी अनुरोधों को एक ही AppDomain में किसी भी पृष्ठभूमि थ्रेड्स के साथ परोसा जाता है जिसे आप बना सकते हैं। दिए गए कारणों में से कोई भी एक "बुरा विचार" नहीं है, मुझे समझाने के रूप में हड़ताल करें। AppDomains नीचे जा सकते हैं, हाँ - लेकिन यह शायद ही ASP.NET पर्यावरण के लिए अद्वितीय है। आपको अपने होस्टिंग वातावरण (Google के लिए HostingEnvironment.RegisterObject) के साथ अच्छा खेलना होगा ।
जॉन

3
.NET 4.5.2 ने QueueBackgroundWorkItemपृष्ठभूमि कार्यों को आसानी से पंजीकृत करने के लिए एक नई सुविधा जोड़ी है , आप अपने उत्तर को फिर से अपडेट करना चाह सकते हैं।
स्कॉट चेम्बरलेन

39

मैं स्वीकृत उत्तर से असहमत हूं।

Task.Factory.StartNewASP.NET में बैकग्राउंड थ्रेड (या किसी कार्य से शुरू किया गया ) का उपयोग ठीक है। सभी होस्टिंग वातावरण के साथ, आप शटडाउन को नियंत्रित करने वाली सुविधाओं को समझना और सहयोग करना चाहते हैं।

ASP.NET में, आप HostingEnvironment.RegisterObjectविधि का उपयोग करके शटडाउन पर शालीनतापूर्वक रोकने के लिए आवश्यक कार्य पंजीकृत कर सकते हैं । इस लेख और टिप्पणियों को चर्चा के लिए देखें ।

(जैसा कि जेरार्ड अपनी टिप्पणी में बताते हैं, अब HostingEnvironment.QueueBackgroundWorkItemवह भी है जो RegisterObjectपृष्ठभूमि आइटम के लिए एक अनुसूचक को पंजीकृत करने के लिए काम करने के लिए नीचे कॉल करता है। कुल मिलाकर नया तरीका अच्छा है क्योंकि यह कार्य-आधारित है।)

सामान्य विषय के रूप में जिसे आप अक्सर सुनते हैं कि यह एक बुरा विचार है, एक विंडोज़ सेवा (या किसी अन्य प्रकार की अतिरिक्त-प्रक्रिया अनुप्रयोग) को लागू करने के विकल्प पर विचार करें:

  • वेब परिनियोजन के साथ और अधिक तुच्छ तैनाती नहीं है
  • विशुद्ध रूप से एज़्योर वेबसाइटों पर तैनात नहीं है
  • पृष्ठभूमि कार्य की प्रकृति के आधार पर, प्रक्रियाओं को संवाद करने की संभावना होगी। इसका मतलब है कि या तो आईपीसी के कुछ रूप या सेवा को एक आम डेटाबेस तक पहुंचना होगा।

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


यह भी खूब रही। मेरे पास एक कार्य है जिसे पूरा करने के लिए ~ 30 सेकंड की आवश्यकता है। बिल्कुल सही अगर आपको काम पूरा करने के लिए बस ऐप पूल को देर करने की ज़रूरत है।
स्कूबा स्टीव

1
.Net फ्रेमवर्क 4.5.2 से आप HostingEnvironment.QueueBackgroundWorkItem (एक्शन <कैंसिलेशनटोकन>) का उपयोग कर सकते हैं
जेरार्ड कार्बो

मेरी टिप्पणियों में ऐसा लगता है कि IIS अंततः ASP.NET वेब एपीआई को बंद कर देता है जो मैं चला रहा हूं और जब तक एक नया अनुरोध नहीं आता है तब तक इसे वापस शुरू नहीं करता है। इसलिए नियत समय पर जब मेरा धागा एप्लिकेशन को किक करने वाला होता है। भाग भी नहीं रहे हैं। क्या मैं इस बारे में गलत हूं?
डेविड सोपको

7

आप इस कार्य के लिए IIS थ्रेड पूल से एक थ्रेड का उपयोग नहीं करना चाहेंगे क्योंकि यह उस थ्रेड को भविष्य के अनुरोध को संसाधित करने में असमर्थ छोड़ देगा। आप ASP.NET 2.0 में एसिंक्रोनस पेज में देख सकते हैं , लेकिन यह वास्तव में सही उत्तर नहीं होगा। इसके बजाय, ऐसा क्या लगता है कि आप इससे लाभान्वित होंगे, Microsoft संदेश कतार में लग रहा है । अनिवार्य रूप से, आप कार्य विवरण कतार में जोड़ देंगे और एक अन्य पृष्ठभूमि प्रक्रिया (संभवतः एक Windows सेवा) उस कार्य को करने के लिए प्रभारी होगी। लेकिन लब्बोलुआब यह है कि पृष्ठभूमि की प्रक्रिया आईआईएस से पूरी तरह से अलग है।


आह, एमएसएमक्यू - मेरी दीर्घकालिक पसंदीदा प्रौद्योगिकियों में से एक। अंतर्दृष्टि और लिंक के लिए धन्यवाद।
Frans

6

मैं ऐसी आवश्यकताओं के लिए HangFire का उपयोग करने का सुझाव दूंगा । इसकी अच्छी आग और भुलक्कड़ इंजन पृष्ठभूमि में चलता है, विभिन्न वास्तुकला का समर्थन करता है, विश्वसनीय है क्योंकि यह दृढ़ता भंडारण द्वारा समर्थित है।


5

यहाँ एक अच्छा धागा और नमूना कोड है: http://forums.asp.net/t/1534903.aspx?PageIndex=2

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

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

string tempStr = GetUrlPageSource("http://www.mysite.com/keepalive.aspx");


    public static string GetUrlPageSource(string url)
    {
        string returnString = "";

        try
        {
            Uri uri = new Uri(url);
            if (uri.Scheme == Uri.UriSchemeHttp)
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
                CookieContainer cookieJar = new CookieContainer();

                req.CookieContainer = cookieJar;

                //set the request timeout to 60 seconds
                req.Timeout = 60000;
                req.UserAgent = "MyAgent";

                //we do not want to request a persistent connection
                req.KeepAlive = false;

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream stream = resp.GetResponseStream();
                StreamReader sr = new StreamReader(stream);

                returnString = sr.ReadToEnd();

                sr.Close();
                stream.Close();
                resp.Close();
            }
        }
        catch
        {
            returnString = "";
        }

        return returnString;
    }

5

हमने इस पथ को शुरू किया, और यह वास्तव में ठीक काम किया जब हमारा ऐप एक सर्वर पर था। जब हम कई मशीनों को स्केल करना चाहते थे (या वेब वेन में कई w3wp का उपयोग करते हैं) तो हमें एक काम को सुनिश्चित करने के लिए सही ढंग से लॉक करने की कार्य कतार, त्रुटि हैंडलिंग, रिट्रीज़ और मुश्किल समस्या का प्रबंधन करने के लिए फिर से मूल्यांकन करना और देखना था। सर्वर अगले आइटम को चुनता है।

... हमने महसूस किया कि हम पृष्ठभूमि प्रसंस्करण इंजनों के लेखन के व्यवसाय में नहीं हैं इसलिए हमने मौजूदा समाधानों की तलाश की और हम भयानक प्रोजेक्ट प्रोजेक्ट फायरफायर का उपयोग करके उतर गए

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

इसका मूल सेटअप भंडारण के रूप में sql सर्वर का उपयोग करता है, लेकिन जब आप इसका समय बढ़ाते हैं तो आप Redis या MSMQ के लिए स्वैप कर सकते हैं। इसमें सभी नौकरियों और उनकी स्थिति को देखने और आपको नौकरियों को फिर से कतार में लाने की अनुमति देने के लिए एक उत्कृष्ट यूआई है।

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

उपलब्ध विकल्पों के बारे में कुछ और परिप्रेक्ष्य के लिए स्कॉट हंसेलमैन के ब्लॉग को देखें जो कि asp.net में पृष्ठभूमि नौकरियों को संभालने के लिए कुछ विकल्पों को शामिल करता है। (उन्होंने हैंगफायर को एक चमकदार समीक्षा दी)

इसके अलावा जॉन ने फिल हैक के ब्लॉग को पढ़ने के लायक होने के कारण संदर्भित किया है कि दृष्टिकोण समस्याग्रस्त क्यों है, और जब एपडोमेन अनलोड किया जाता है तो थ्रेड पर काम को कैसे रोकना है।


2

क्या आप उस कार्य को करने के लिए एक विंडोज़ सेवा बना सकते हैं? तब कार्रवाई करने के लिए Windows सेवा को कॉल करने के लिए वेब सर्वर से .NET रीमोटिंग का उपयोग करें? अगर ऐसा है तो मैं यही करूंगा।

यह IIS पर रिले करने की आवश्यकता को समाप्त कर देगा, और इसकी कुछ प्रसंस्करण शक्ति को सीमित कर देगा।

यदि नहीं तो मैं इस प्रक्रिया को पूरा करने के लिए उपयोगकर्ता को वहाँ बैठने के लिए मजबूर करूँगा। इस तरह से आप यह सुनिश्चित करते हैं कि यह पूरा हो गया है और IIS द्वारा नहीं मारा गया है।


2

IIS में लंबे समय से चल रहे काम को होस्ट करने का एक समर्थित तरीका प्रतीत होता है। वर्कफ़्लो सर्विसेज इसके लिए डिज़ाइन की गई लगती हैं, विशेष रूप से विंडोज सर्वर ऐपफाइब्रिकेशन के साथ । डिज़ाइन ऑटोमैटिक दृढ़ता और लंबे समय से चल रहे काम को फिर से शुरू करने का समर्थन करके एप्लीकेशन पूल रीसाइक्लिंग के लिए अनुमति देता है।


2

आप पृष्ठभूमि में कार्य चला सकते हैं और अनुरोध समाप्त होने के बाद भी वे पूरा हो जाएगा। एक अनकहा अपवाद को फेंकने न दें । आम तौर पर आप हमेशा अपने अपवादों को फेंकना चाहते हैं। यदि एक अपवाद को एक नए धागे में फेंक दिया जाता है, तो यह IIS कार्यकर्ता प्रक्रिया को क्रैश कर देगा - w3wp.exe , क्योंकि अब आप अनुरोध के संदर्भ में नहीं हैं। यदि आप इनका उपयोग कर रहे हैं तो इन-प्रोसेस मेमोरी समर्थित सत्रों के अतिरिक्त आपके द्वारा चलाए जा रहे किसी भी अन्य पृष्ठभूमि कार्यों को मारने के लिए भी है। यह निदान करना मुश्किल होगा, यही वजह है कि अभ्यास को हतोत्साहित किया जाता है।


1

Async कार्य चलाने के लिए बस एक किराए की प्रक्रिया बनाएँ; यह एक Windows सेवा नहीं है (हालांकि यह ज्यादातर मामलों में अधिक इष्टतम दृष्टिकोण है। MSMQ को मारने का तरीका है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.