मेरे पास सी # (.NET 1.1) में लिखी गई एक सेवा है और यह हर रात मध्यरात्रि में कुछ सफाई कार्य करने की इच्छा रखती है। मुझे सेवा के भीतर निहित सभी कोड रखना है, तो इसे पूरा करने का सबसे आसान तरीका क्या है? Thread.Sleep()
का उपयोग और समय के साथ जांचने की जांच?मैं रोज़ाना कार्य करने के लिए सी # विंडोज सेवा कैसे निर्धारित कर सकता हूं?
उत्तर
मैं Thread.Sleep का उपयोग नहीं होगा():
यहाँ इसके उपयोग की एक त्वरित उदाहरण है। (उदाहरण के लिए हर 10 मिनट में) या तो एक निर्धारित कार्य का उपयोग करें (के रूप में दूसरों का उल्लेख किया है), या अपने सेवा है, जो समय-समय पर आग के अंदर एक टाइमर सेट और देखें कि क्या तारीख पिछले रन के बाद से बदल:
private Timer _timer;
private DateTime _lastRun = DateTime.Now.AddDays(-1);
protected override void OnStart(string[] args)
{
_timer = new Timer(10 * 60 * 1000); // every 10 minutes
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
//...
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// ignore the time, just compare the date
if (_lastRun.Date < DateTime.Now.Date)
{
// stop the timer while we are running the cleanup task
_timer.Stop();
//
// do cleanup stuff
//
_lastRun = DateTime.Now;
_timer.Start();
}
}
क्या मध्यरात्रि में टाइमर को समाप्त करने के लिए इसे और अधिक समझदारी नहीं होगी, समय की जांच करने के लिए हर मिनट जागने के बजाय? – Kibbee
@ किबीबी: हो सकता है कि सेवा मध्यरात्रि (किसी भी कारण से) नहीं चल रही हो, तो हो सकता है कि आप सेवा को फिर से चलने के तुरंत बाद कार्य निष्पादित करना चाहें। – M4N
फिर आपको यह पता लगाने के लिए सेवा के स्टार्ट-अप में कुछ कोड जोड़ना चाहिए कि आपको तुरंत भागना चाहिए, क्योंकि सेवा नहीं चल रही थी, और यह होना चाहिए। आपको लगातार हर 10 मिनट की जांच नहीं करनी चाहिए।जांचें कि क्या आपको स्टार्टअप पर चलना चाहिए, और फिर अगली बार चलाने के लिए पता नहीं लगाना चाहिए। उसके बाद, और एक टाइमर सेट करें, हालांकि आपको इसकी आवश्यकता है। – Kibbee
जिस तरह से मैं इसे पूरा करता हूं वह टाइमर के साथ होता है।
सर्वर टाइमर चलाएं, क्या यह हर 60 सेकंड में घंटा/मिनट की जांच करें।
यदि यह सही घंटा/मिनट है, तो अपनी प्रक्रिया चलाएं।
मैं वास्तव में इसे एक बेस क्लास में समझा गया हूं जिसे मैं वनडेयरुनर कहते हैं।
मुझे कोड को थोड़ा साफ करने दें और मैं इसे यहां पोस्ट करूंगा।
private void OnceADayRunnerTimer_Elapsed(object sender, ElapsedEventArgs e)
{
using (NDC.Push(GetType().Name))
{
try
{
log.DebugFormat("Checking if it's time to process at: {0}", e.SignalTime);
log.DebugFormat("IsTestMode: {0}", IsTestMode);
if ((e.SignalTime.Minute == MinuteToCheck && e.SignalTime.Hour == HourToCheck) || IsTestMode)
{
log.InfoFormat("Processing at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute);
OnceADayTimer.Enabled = false;
OnceADayMethod();
OnceADayTimer.Enabled = true;
IsTestMode = false;
}
else
{
log.DebugFormat("Not correct time at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute);
}
}
catch (Exception ex)
{
OnceADayTimer.Enabled = true;
log.Error(ex.ToString());
}
OnceADayTimer.Start();
}
}
विधि का मांस e.SignalTime.Minute/घंटे की जांच कर रही है।
वहां परीक्षण के लिए वहां हुक हैं, लेकिन यह आपका बीतदार टाइमर यह सब काम करने जैसा दिख सकता है।
थोड़ा सा एक व्यस्त सर्वर के कारण देरी से यह घंटे + मिनट याद आ सकता है। –
सच है। जब मैंने ऐसा किया, मैंने जांच की: क्या अब 00:00 से अधिक समय है? यदि हां, तो क्या यह नौकरी खत्म होने के 24 घंटों से अधिक है? यदि ऐसा है, तो नौकरी चलाएं, अन्यथा फिर से प्रतीक्षा करें। – ZombieSheep
क्या यह एक वास्तविक सेवा होनी चाहिए? क्या आप विंडोज नियंत्रण कक्ष में निर्मित निर्धारित कार्यों का उपयोग कर सकते हैं।
चूंकि सेवा पहले से मौजूद है, इसलिए कार्यक्षमता को जोड़ना आसान हो सकता है। – M4N
कंसोल ऐप में इस तरह की एक संकीर्ण उद्देश्य सेवा को परिवर्तित करना तुच्छ होना चाहिए। –
उसने पहले ही कहा है, "मुझे सेवा के भीतर निहित सभी कोड रखना है"। मुझे नहीं लगता कि मूल आवश्यकताओं पर सवाल उठाना जरूरी है। यह निर्भर करता है, लेकिन कभी-कभी निर्धारित समय पर सेवा का उपयोग करने के बहुत अच्छे कारण होते हैं। – jeremcc
एक दैनिक कार्य? लगता है कि यह सिर्फ एक निर्धारित कार्य (नियंत्रण कक्ष) होना चाहिए - यहां किसी सेवा की आवश्यकता नहीं है।
Quartz.NET देखें। आप इसे विंडोज सेवा के भीतर उपयोग कर सकते हैं। यह आपको एक कॉन्फ़िगर किए गए शेड्यूल के आधार पर नौकरी चलाने की अनुमति देता है, और यह एक साधारण "क्रॉन जॉब" वाक्यविन्यास का भी समर्थन करता है। मुझे इसके साथ बहुत सफलता मिली है।
// Instantiate the Quartz.NET scheduler
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
// Instantiate the JobDetail object passing in the type of your
// custom job class. Your class merely needs to implement a simple
// interface with a single method called "Execute".
var job = new JobDetail("job1", "group1", typeof(MyJobClass));
// Instantiate a trigger using the basic cron syntax.
// This tells it to run at 1AM every Monday - Friday.
var trigger = new CronTrigger(
"trigger1", "group1", "job1", "group1", "0 0 1 ? * MON-FRI");
// Add the job to the scheduler
scheduler.AddJob(job, true);
scheduler.ScheduleJob(trigger);
एक अच्छा सुझाव - जैसे ही आप मूल टाइमर सामान की तुलना में थोड़ा अधिक जटिल करते हैं, आपको क्वार्ट्ज को देखना चाहिए। – serg10
क्वार्ट्ज का उपयोग करना इतना आसान है, मैं तर्क दूंगा कि यहां तक कि एक सुपर-सरल कार्य के लिए, आगे बढ़ें और इसका उपयोग करें। यह शेड्यूलिंग को आसानी से समायोजित करने की क्षमता देगा। –
सुपर सरल वास्तव में नहीं है? अधिकांश नए लोग यहां इस समस्या को पकड़ेंगे http://stackoverflow.com/questions/24628372/quartz-job-scheduler-in-windows- सेवा – batmaci
मैं सुझाव देगा कि आप टाइमर का उपयोग करें, लेकिन इसे हर 45 सेकंड में जांचने के लिए सेट करें, मिनट नहीं। अन्यथा आप परिस्थितियों में भाग ले सकते हैं जहां भारी भार के साथ, किसी विशेष मिनट की जांच मिस्ड हो जाती है, क्योंकि टाइमर ट्रिगर्स के समय और आपका कोड चलने का समय और वर्तमान समय की जांच करता है, तो हो सकता है कि आपने लक्ष्य मिनट को याद किया हो।
यदि आप यह सुनिश्चित करने के लिए जांच नहीं कर रहे हैं कि यह पहले से ही एक बार नहीं चला है, तो संभावना है कि आप कभी भी 45 सेकंड की जांच कर रहे हैं तो आप दो बार 00:00 हिट कर सकते हैं। –
अच्छा प्वाइंट। जांच प्रक्रिया के अंत में स्लीप (15000) को कॉल करके इस समस्या से बचा जा सकता है। (या शायद 16000 एमएस, सुरक्षित पक्ष पर रहने के लिए ;-) – Treb
मैं सहमत हूं, आपको यह जांचना चाहिए कि यह पहले से चल रहा है या नहीं, भले ही आप किस टाइमर अवधि को चुनते हों। – GWLlosa
जैसा कि पहले से ही लिखा है, आपके द्वारा वर्णित परिदृश्य में एक टाइमर सबसे अच्छा विकल्प है।
आपकी सटीक आवश्यकताओं के आधार पर, हर मिनट वर्तमान समय की जांच आवश्यक नहीं हो सकता है। यदि आपको मध्यरात्रि में ठीक निष्पादित करने की आवश्यकता नहीं है, लेकिन मध्यरात्रि के ठीक बाद एक घंटे के भीतर, आप केवल Martin's approach के लिए जा सकते हैं, यह जांचने के लिए कि तिथि बदल गई है या नहीं।
यदि आप आधी रात को अपनी कार्रवाई करना चाहते हैं तो यह है कि आप अपने कंप्यूटर पर कम वर्कलोड की उम्मीद करते हैं, बेहतर देखभाल करते हैं: वही धारणा अक्सर दूसरों द्वारा बनाई जाती है, और अचानक आपके पास 100 सफाई कार्य होते हैं जो 0 के बीच लात मारते हैं : 00 और 0:01 बजे
उस स्थिति में आपको अलग-अलग समय पर अपना क्लीनअप शुरू करने पर विचार करना चाहिए। मैं आमतौर पर उन चीजों घड़ी घंटे में नहीं करते हैं, लेकिन आधे घंटे में (1.30 बजे किया जा रहा है मेरी निजी पसंद)
इस प्रयास करें:
public partial class Service : ServiceBase
{
private Timer timer;
public Service()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
SetTimer();
}
private void SetTimer()
{
if (timer == null)
{
timer = new Timer();
timer.AutoReset = true;
timer.Interval = 60000 * Convert.ToDouble(ConfigurationManager.AppSettings["IntervalMinutes"]);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
}
private void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
//Do some thing logic here
}
protected override void OnStop()
{
// disposed all service objects
}
}
आप यहां http://visualstudiogallery.msdn.microsoft.com/a4a4f042-ffd3-42f2-a689-290ec13011f8
लागू TaskSchedulerLibrary कोशिश कर सकते हैं सार वर्ग AbstractScheduledTask
और ScheduleUtilityFactory.AddScheduleTaskToBatch
स्थिर विधि
यहाँ फोन कोड के अपने टुकड़ा है जो काम करता है:
protected override void OnStart(string[] args)
{
timer = new Timer(); //Initialize the globally declared timer
//SETTING THE INTERVAL FROM CONFIG FILE (10 SECONDS)
timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["TimerInterval"]);
timer.Enabled = true;
timer.Elapsed += timer_Elapsed;
}
अपने गुजरे घटना में, आप यह कर सकते हैं:
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Enabled = false;
string ScheduleTime = GlobalVariables.ScheduledTime;//GETTING SCHEDULED TIME FROM CONFIG IN (HH:mm) FORMAT
string CurrentHourMin = DateTime.Now.ToString("HH:mm");//GETTING CURRENT TIME IN HH:mm format
if (ScheduleTime == CurrentHourMin)
{
// YOUR CODE
}
System.Threading.Thread.Sleep(60000); //Putting thread to sleep for 60 seconds to skip the current minute to avoid re-execution of code
timer.Enabled = true;
}
आप वास्तव में एक .NET प्रक्रिया है कि स्मृति, पूरे दिन में बैठता है, और आधी रात को कुछ करता है बनाने के लिए करना चाहते हैं? आप अपने उपकरण को स्थापित करने पर, वास्तव में क्यों नहीं कर सकते हैं, एक सिस्टम इवेंट सेट करें जो मध्यरात्रि (या कुछ अन्य कॉन्फ़िगर करने योग्य समय) पर आग लगती है जो आपके ऐप को शुरू करती है, क्या इसकी बात होती है, फिर चली जाती है? –
मुझे पता है कि अगर मैं पाया कि मेरे पास 20-40 मेगाहर्ट्ज मेमोरी का उपभोग करने वाली एक प्रबंधित सेवा है, तो हर समय चल रहा है, जो दिन में एक बार छोड़कर कुछ भी नहीं करता है। :) –
इसकी डुप्लिकेट [लिंक] (http://stackoverflow.com/questions/503564/how-might-i-schedule-ac-sharp-windows-service-to-perform-a-task- दैनिक) – csa