मेरे पास C # (.NET 1.1) में लिखी गई सेवा है और मैं चाहता हूं कि यह हर रात आधी रात को कुछ सफाई कार्य करे। मुझे सेवा के भीतर सभी कोड रखने होंगे, इसलिए इसे पूरा करने का सबसे आसान तरीका क्या है? Thread.Sleep()
समय-समय पर रोलिंग के लिए उपयोग और जाँच?
मेरे पास C # (.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();
}
}
की जाँच करें Quartz.NET । आप इसे Windows सेवा के भीतर उपयोग कर सकते हैं। यह आपको कॉन्फ़िगर शेड्यूल के आधार पर नौकरी चलाने की अनुमति देता है, और यह एक सरल "क्रोन जॉब" सिंटैक्स का भी समर्थन करता है। मुझे इसके साथ बहुत सफलता मिली है।
यहाँ इसके उपयोग का एक त्वरित उदाहरण है:
// 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);
एक दैनिक कार्य? ऐसा लगता है कि यह केवल एक निर्धारित कार्य (नियंत्रण कक्ष) होना चाहिए - यहां किसी सेवा की आवश्यकता नहीं है।
क्या यह एक वास्तविक सेवा होना चाहिए? क्या आप केवल विंडोज़ कंट्रोल पैनल में अनुसूचित कार्यों में निर्मित उपयोग कर सकते हैं।
जिस तरह से मैं इसे पूरा करता हूं वह एक टाइमर के साथ है।
एक सर्वर टाइमर चलाएँ, यह हर 60 सेकंड में घंटा / मिनट की जाँच करें।
यदि यह सही समय / मिनट है, तो अपनी प्रक्रिया चलाएं।
मैं वास्तव में इस आधार वर्ग में एक बार बाहर हो गया हूं जिसे मैं एक बार OneADayRunner कहता हूं।
मुझे कोड को थोड़ा साफ करने दो और मैं इसे यहाँ पोस्ट करूँगा।
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();
}
}
विधि का गोमांस ई.सिग्नलटाइम में है। एमिन्यूट / आवर चेक।
परीक्षण आदि के लिए वहाँ हुक हैं, लेकिन यह वही है जो आपका बीता हुआ टाइमर यह सब काम करने के लिए पसंद कर सकता है।
जैसा कि दूसरों ने पहले ही लिखा है, आपके द्वारा वर्णित परिदृश्य में एक टाइमर सबसे अच्छा विकल्प है।
आपकी सटीक आवश्यकताओं के आधार पर, वर्तमान समय की जाँच करना हर मिनट आवश्यक नहीं हो सकता है। आप कार्रवाई करने के लिए की जरूरत है नहीं वास्तव में आधी रात को, लेकिन सिर्फ आधी रात के बाद एक घंटे के भीतर, आप के लिए जा सकते हैं मार्टिन दृष्टिकोण केवल यह पता चल सके की तारीख बदल गया है की।
यदि आप आधी रात को अपना कार्य करना चाहते हैं, तो यह है कि आप अपने कंप्यूटर पर कम कार्यभार की अपेक्षा करते हैं, बेहतर देखभाल करते हैं: एक ही धारणा अक्सर दूसरों द्वारा बनाई जाती है, और अचानक आपके पास 0:00 और 0 के बीच 100 सफाई क्रियाएं होती हैं। : ०१ बजे
उस स्थिति में आपको एक अलग समय पर अपना सफाई शुरू करने पर विचार करना चाहिए। मैं आमतौर पर घड़ी की घड़ी में नहीं, बल्कि आधे घंटे में (1.30 बजे मेरी व्यक्तिगत पसंद है)
मेरा सुझाव है कि आप एक टाइमर का उपयोग करें, लेकिन इसे हर 45 सेकंड में जांचने के लिए सेट करें, मिनट नहीं। अन्यथा आप उन परिस्थितियों में भाग सकते हैं जहां भारी भार के साथ, किसी विशेष मिनट के लिए चेक छूट जाता है, क्योंकि समय के बीच टाइमर ट्रिगर होता है और जिस समय आपका कोड चलता है और वर्तमान समय की जांच करता है, आप लक्ष्य मिनट से चूक गए होंगे।
आप यहां टास्कस्क्राइडर लय को भी देख सकते हैं। http://visualstudiogallery.msdn.microsoft.com/a4a4f042-ffd3-42f2-a689-290ec13011f8
अमूर्त वर्ग को लागू AbstractScheduledTask
करें और ScheduleUtilityFactory.AddScheduleTaskToBatch
स्थिर विधि को कॉल करें
उन लोगों के लिए जो उपरोक्त समाधानों को काम नहीं करते हैं, यह इसलिए है क्योंकि आपके पास this
आपकी कक्षा हो सकती है , जो एक विस्तार विधि का अर्थ है, जो त्रुटि संदेश कहता है, केवल गैर-सामान्य स्थिर वर्ग पर समझ में आता है। आपकी कक्षा स्थिर नहीं है। यह ऐसा कुछ प्रतीत नहीं होता है जो एक विस्तार विधि के रूप में समझ में आता है, क्योंकि यह उदाहरण में प्रश्न पर कार्य कर रहा है, इसलिए इसे हटा दें this
।
इसे इस्तेमाल करे:
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
}
}