2013-10-30 4 views
13

को मतदान करने के लिए एक सी # विंडोज सेवा बनाना मैं एक ऐसी सेवा लिखना चाहता हूं जो डाटाबेस का चुनाव करे और वापस लाए जा रहे डेटा के आधार पर एक ऑपरेशन करे।डेटाबेस

मुझे यकीन नहीं है कि ऐसा करने का सबसे अच्छा तरीका क्या है, मुझे इसके बारे में कुछ ब्लॉग मिल सकते हैं और यह स्टैक ओवरफ़्लो प्रश्न Polling Service - C# है। हालांकि मैं सावधान हूं कि वे सभी पुराने और संभवतः पुराने हैं।

क्या कोई मुझे इस तरह कुछ करने पर वर्तमान सलाह या सर्वोत्तम प्रथाओं (अगर कोई है) पर सलाह दे सकता है या मुझे इस बारे में एक और हालिया ब्लॉग पोस्ट की दिशा में इंगित कर सकता है। टाइमर या टीपीएल कार्यों का उपयोग करके मैं जो भी इकट्ठा कर सकता हूं उससे यह करने के दो संभावित तरीके हैं।

यदि टाइमर अभी भी सुझाए गए हैं तो सेवा बंद होने पर वे कैसे काम करेंगे, क्योंकि इन सेवाओं के लिए मेरे द्वारा किए जाने वाले संचालन संभावित रूप से 30+ मिनट ले सकते हैं, इसलिए मैं उपयोग कार्यों का उपयोग करता हूं क्योंकि मैं कार्य रद्दीकरण का उपयोग कर सकता हूं टोकन लेकिन रद्द होने पर इन फेंक अपवाद (अगर मैं गलत हूं तो मुझे सही करें) और मुझे नहीं लगता कि मैं वास्तव में उस व्यवहार को चाहता हूं (हालांकि मुझे लगता है कि अगर आपको लगता है कि कोई कारण है तो मैं इसे सही करूंगा)।

क्षमा करें कि मैं एक प्रश्न में काफी कुछ पूछ रहा हूं लेकिन मुझे पूरी तरह से यकीन नहीं है कि मैं क्या पूछ रहा हूं।

+0

मैं शुरुआत करने वालों के लिए निर्माता-उपभोक्ता पैटर्न को देखता हूं। एक धागा नौकरी की जानकारी को इकट्ठा और एकत्र कर सकता है, फिर इसे कतार हैंडलर पर भेज दें। –

+0

आप डेटाबेस को कितनी बार मतदान करेंगे? क्या यह * सब * है कि सेवा करेगा? यदि सभी सेवा डेटाबेस को बार-बार मतदान करती है और संभावित रूप से एक बहुत लंबा कार्य चलाती है, तो आप शायद एक सादे पुराने कंसोल एप्लिकेशन लिखने और इसे विंडोज़ में एक निर्धारित कार्य के रूप में स्थापित करने से बेहतर हो। –

+0

क्या आपके पास कोई लिंक है कि कोड अनुदान में इसे कैसे कार्यान्वित किया जा सकता है? जिम - मैं इसे शायद 2 मिनट तक मतदान करने की योजना बना रहा हूं। और हाँ यह सब सेवा होगी लेकिन मैं बाद में ऑनलाइन फ़ीड की निगरानी करने के लिए अतिरिक्त कार्यक्षमता भी जोड़ सकता हूं। – user2647347

उत्तर

23

जाओ। एक निर्धारित कार्य का उपयोग करना एक बुरा विचार नहीं है, लेकिन चूंकि आपने कहा है कि चुनाव हर 2 मिनट में हो सकते हैं तो आप शायद सेवा के साथ जाने से बेहतर हो सकते हैं। यह सेवा आपको चुनावों के बीच राज्य बनाए रखने की अनुमति देगी और आप चुनाव के समय पर भी अधिक नियंत्रण रखेंगे। आपने कहा कि ऑपरेशन को निकाल दिए जाने के बाद ऑपरेशन में 30+ मिनट लग सकते हैं ताकि आप ऑपरेशन पूरा होने तक चुनाव स्थगित करना चाहें। जब तर्क एक सेवा के रूप में चलाया जाता है तो यह करना थोड़ा आसान होता है।

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

यहां एक बहुत ही सामान्य टेम्पलेट है जिसका उपयोग आप शुरू करने के लिए कर सकते हैं।

public class YourService : ServiceBase 
{ 
    private CancellationTokenSource cts = new CancellationTokenSource(); 
    private Task mainTask = null; 

    protected override void OnStart(string[] args) 
    { 
    mainTask = new Task(Poll, cts.Token, TaskCreationOptions.LongRunning); 
    mainTask.Start(); 
    } 

    protected override void OnStop() 
    { 
    cts.Cancel(); 
    mainTask.Wait(); 
    } 

    private void Poll() 
    { 
    CancellationToken cancellation = cts.Token; 
    TimeSpan interval = TimeSpan.Zero; 
    while (!cancellation.WaitHandle.WaitOne(interval)) 
    { 
     try 
     { 
     // Put your code to poll here. 
     // Occasionally check the cancellation state. 
     if (cancellation.IsCancellationRequested) 
     { 
      break; 
     } 
     interval = WaitAfterSuccessInterval; 
     } 
     catch (Exception caught) 
     { 
     // Log the exception. 
     interval = WaitAfterErrorInterval; 
     } 
    } 
    } 
} 

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

+0

मुझे वेटहैंडलर के उपयोग को पसंद है, ऐसा लगता है कि यह एक क्लीनर तंत्र के लिए स्वयं को एक टाइमर विशेष रूप से उधार देता है। मुझे भविष्य में इसका इस्तेमाल करना होगा। धन्यवाद ब्रायन! –

+0

धन्यवाद, मेरे पास कुछ समान था लेकिन रद्दीकरण।WaitHandle.WaitOne (अंतराल) मुझे लगता है कि मैं याद कर रहा था। – user2647347

+0

मैंने इस टेम्पलेट का उपयोग किया, और कभी-कभी मेरी servie बस frezes, और मुझे इसे रोकने के लिए प्रक्रिया को मारने की जरूरत है, कोई अपवाद नहीं, कोई विचार? या मैं क्या देख सकता हूँ? – kosnkov

3

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

Windows Task Scheduler

अगले जिस तरह से आप ऐसा कर सकता है एक खिड़कियों सेवा बनाने के लिए किया जाएगा और कहा कि सेवा में एक टाइमर, विशेष रूप से System.Timers.Timer का उपयोग करें। अनिवार्य रूप से आप टाइमर अंतराल को उस समय तक निर्धारित करेंगे जब आप अपनी प्रक्रिया को चलाने से पहले पास करना चाहते हैं। फिर आप टाइमर टिक घटना के लिए साइन अप करेंगे जो अंतराल के हर बार आग लग जाएगा। इस घटना में आपको अनिवार्य रूप से वह प्रक्रिया होगी जिसे आप चलाना चाहते हैं; यदि आप चाहें तो यह अतिरिक्त थ्रेड को लात मार सकता है। फिर उस प्रारंभिक सेटअप के बाद आप टाइमर स्टार्ट() फ़ंक्शन को कॉल करेंगे या टाइमर शुरू करने के लिए सक्षम प्रॉपर्टी को True पर सेट करेंगे। ऑब्जेक्ट का वर्णन करने वाले एमएसडीएन पेज पर उदाहरण के रूप में यह कैसा दिखता है इसका एक अच्छा उदाहरण मिल सकता है। वहाँ बहुत सारे ट्यूटोरियल हैं जो दिखाते हैं कि विंडोज़ सेवा कैसे स्थापित करें ताकि मैं उस विशेष रूप से जाने से परेशान न हो।

MSDN: System.Timers.Timer

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

Using SqlDependency To Monitor SQL Database Changes


दो बातें मैं अपने मूल पद से करते रहे कि सवाल आप था लिए विशिष्ट नहीं हैं चाहते हैं।

  1. यदि आप एक असली विंडोज सेवा लिख ​​रहे हैं तो आप सेवा को रोकना नहीं चाहते हैं। सेवा लगातार चलनी चाहिए और यदि कोई अपवाद होता है तो इसे उचित तरीके से संभाला जाना चाहिए और सेवा को रोकना नहीं चाहिए।

  2. रद्दीकरण टोकन को अपवाद फेंकना नहीं है; बस ThrowIfCancellationRequested() को कॉल नहीं करने का अपवाद नहीं फेंक दिया जाएगा या यदि यह रद्दीकरण टोकनसोर्स है तो रद्द करें विधि पर गलत पर तर्क सेट करें, फिर बाद में टोकन को जांचें कि यह देखने के लिए कि क्या आपके थ्रेड में रद्दीकरण का अनुरोध किया गया है और थ्रेड से बाहर निकलता है यदि ऐसा है तो।

उदाहरण के लिए:

इस के लिए एक Windows सेवा के साथ
CancellationTokenSource cts = new CancellationTokenSource(); 
    ParallelOptions options = new ParallelOptions 
    { 
     CancellationToken = cts.Token 
    }; 
    Parallel.ForEach(data, options, i => 
    { 
     try 
     { 
      if (cts.IsCancellationRequested) return; 

      //do stuff 

     } 
     catch (Exception ex) 
     { 
      cts.Cancel(false); 
     } 
    });