I created a windows service, which will send mails to users based up on some conditions.
I had it installed on server in automatic mode. From the logs i can see that it ran successfully for first time and ended.
And i did not see it running again in the logs after that.
I checked the service in admin tools and it says it is started.
I also restarted service but no use, it did not start again.
Below is the code i used to start the service.
public partial class ScheduledService : ServiceBase
{
Timer timer;
private DateTime lastRun = DateTime.Now;
private DateTime DailyRunTime = Convert.ToDateTime(System.Configuration.ConfigurationManager.AppSettings["DailyRunTime"]);
public ScheduledService()
{
InitializeComponent();
//GetDocRetentionList DocList = new GetDocRetentionList();
//DocList.GetDataSet();
}
protected override void OnStart(string[] args)
{
//System.Diagnostics.Debugger.Launch();
TraceService("start service");
//timer = new Timer(24 * 60 * 60 * 1000);
timer = new Timer(10 * 60 * 1000);
timer.Start();
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
double TimerInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["Timer"]);
timer.Interval = TimerInterval;
timer.Enabled = true;
}
protected override void OnStop()
{
timer.Enabled = false;
TraceService("stopping service");
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
TraceService("Service started at " + DateTime.Now);
if (lastRun.Date < DateTime.Now.Date)
{
if (DateTime.Now > DailyRunTime)
{
GetDocRetentionList DocList = new GetDocRetentionList();
DocList.GetDataSet();
timer.Stop();
lastRun = DateTime.Now.Date;
//timer.Start();
}
}
}
Any help i can get in this regard will be really helpful. Plz let me know.
Well.. your service is set to execute once, then it shuts the timer off in the OnElapsedTime method but never turns itself back on.
The first thing OnElapsedTime should do is turn off the timer. The last thing it should do is turn it back on.
Related
I have console application am using as demo to an App, it prints "hello", based on the timespan its expected to alert the user. when its not yet the timespan, i want to delay the app from printing hello and resume when its time.
public static async void timeCounter(int delae)
{
//This is suppose to cause a delay but it instead initiate the
//TimerOperation_Tick method.
await Task.Delay(delae);
// timer countdown
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000; // 1 second
timer.Elapsed += new ElapsedEventHandler(TimerOperation_Tick);
timer.Start();
if (obj.SubmissionCheck == true)
{
timer.Stop();
}
}
/// the event subscriber
private static void TimerOperation_Tick(object e, ElapsedEventArgs args)
{
if (timeFrame != 0)
{
Console.WriteLine("hi" + timeFrame);
timeFrame --;
if (timeFrame < 1)
{
obj.SubmissionCheck = true;
nt.Remove(obj);
startNotification();
}
}
}
Try setting timer.Enabled = false; This will prevent the timer ticks from occurring.
I had created a windows service and i want that the service will Schedule to run daily at 6:00 Am.
Below is the code which i had written:-
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
ExtractDataFromSharePoint();
}
catch (Exception ex)
{
//Displays and Logs Message
_loggerDetails.LogMessage = ex.ToString();
_writeLog.LogDetails(_loggerDetails.LogLevel_Error, _loggerDetails.LogMessage);
}
}
In the above code you can see that in OnStart Method of service i am calling a Function ExtractDataFromSharePoint(). How i will schedule this to run daily morning at 6:00 AM.
Here, you have 2 ways to execute your application to run at 6 AM daily.
1) Create a console application and through windows scheduler execute on 6 AM.
2) Create a timer (System.Timers.Timer) in your windows service which executes on every defined interval and in your function, you have to check if the system time = 6 AM then execute your code
ServiceTimer = new System.Timers.Timer();
ServiceTimer.Enabled = true;
ServiceTimer.Interval = 60000 * Interval;
ServiceTimer.Elapsed += new System.Timers.ElapsedEventHandler(your function);
Note: In your function you have to write the code to execute your method on 6 AM only not every time
You don't need a service for this. Just create a regular console app, then use the Windows scheduler to run your program at 6am. A service is when you need your program to run all the time.
Here is code that will run within a service every day at 6AM.
include:
using System.Threading;
also ensure you declare your timer within the class:
private System.Threading.Timer _timer = null;
The StartTimer function below takes in a start time and an interval period and is currently set to start at 6AM and run every 24 hours. You could easily change it to start at a different time and interval if needed.
protected override void OnStart(string[] args)
{
// Pass in the time you want to start and the interval
StartTimer(new TimeSpan(6, 0, 0), new TimeSpan(24, 0, 0));
}
protected void StartTimer(TimeSpan scheduledRunTime, TimeSpan timeBetweenEachRun) {
// Initialize timer
double current = DateTime.Now.TimeOfDay.TotalMilliseconds;
double scheduledTime = scheduledRunTime.TotalMilliseconds;
double intervalPeriod = timeBetweenEachRun.TotalMilliseconds;
// calculates the first execution of the method, either its today at the scheduled time or tomorrow (if scheduled time has already occurred today)
double firstExecution = current > scheduledTime ? intervalPeriod - (current - scheduledTime) : scheduledTime - current;
// create callback - this is the method that is called on every interval
TimerCallback callback = new TimerCallback(RunXMLService);
// create timer
_timer = new Timer(callback, null, Convert.ToInt32(firstExecution), Convert.ToInt32(intervalPeriod));
}
public void RunXMLService(object state) {
// Code that runs every interval period
}
Thanks #Rachit for your answer and now I am able to fulfill my requirements.
static System.Timers.Timer _timer;
static string _ScheduledRunningTime ="6:00 AM";
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
_timer = new System.Timers.Timer();
_timer.Interval = TimeSpan.FromMinutes(1).TotalMilliseconds;//Every one minute
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
}
catch (Exception ex)
{
//Displays and Logs Message
_loggerDetails.LogMessage = ex.ToString();
_writeLog.LogDetails(_loggerDetails.LogLevel_Error, _loggerDetails.LogMessage);
}
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//Displays and Logs Message
_loggerDetails.LogMessage = "timer_Elapsed method at :"+DateTime.Now ;
_writeLog.LogDetails(_loggerDetails.LogLevel_Info, _loggerDetails.LogMessage);
string _CurrentTime=String.Format("{0:t}", DateTime.Now);
if (_CurrentTime == _ScheduledRunningTime)
{
ExtractDataFromSharePoint();
}
}
If a service is really required, look at Quartz.NET to do the scheduling for you
http://www.quartz-scheduler.net/
Here is the code that makes a call to DB and set the scheduler time based on the results :
Also, you can call a number of API calls which sends regular SMS/emails here itself.
public void ScheduleService()
{
try
{
dsData = new DataSet();
_timeSchedular = new Timer(new TimerCallback(SchedularCallBack));
dsData = objDataManipulation.GetInitialSMSConfig();
if (dsData.Tables[0].Rows.Count > 0)
{
DateTime scheduledTime = DateTime.MinValue;
scheduledTime = DateTime.Parse(dsData.Tables[0].Rows[0]["AUTOSMSTIME"].ToString());
if (string.Format("{0:dd/MM/YYYY HH:mm}", DateTime.Now) == string.Format("{0:dd/MM/YYYY HH:mm}", scheduledTime))
{
objDataManipulation.WriteToFile("Service Schedule Time Detected");
for (int iRow = 0; iRow < dsData.Tables[0].Rows.Count; iRow++)
{
if (dsData.Tables.Count > 1)
{
if (dsData.Tables[1].Rows.Count > 0)
{
sendData(dsData);
}
}
else
{
objDataManipulation.WriteToFile("No SMS Content Data !");
} }
}
if (DateTime.Now > scheduledTime)
{
scheduledTime = scheduledTime.AddDays(1);
}
TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);
objDataManipulation.WriteToFile("TexRetail Service scheduled to run after: " + schedule + " {0}");
int dueTime = Convert.ToInt32(timeSpan.TotalMilliseconds);
//Change the Timer's Due Time.
_timeSchedular.Change(dueTime, Timeout.Infinite);
}
}
catch (Exception ex)
{
objDataManipulation.WriteToFile("Service Error {0}" + ex.Message + ex.StackTrace + ex.Source);
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController(ServiceName))
{
serviceController.Stop();
}
}
}
actually HERE I AM GETTING TIME INTERVAL FROM app.config file
protected override void OnStart(string[] args)
{
Timer timer = new Timer();
this._dbServiceInterval = int.Parse(ConfigurationManager.AppSettings["ServiceInterval"].ToString());
timer.Interval = (double)this._dbServiceInterval;
timer.Enabled = true;
timer.Start();
timer.Elapsed += new ElapsedEventHandler(this.timerDispatcher_Elapsed);
}
This is my code for Windows Service...but unfortunately, the method myTimer_Elapsed() is invoked only when at least 60 sec. after starting the service. Why not start immediately after switching service?
public partial class MyService : ServiceBase
{
private System.Threading.Thread myWorkingThread;
private System.Timers.Timer myTimer = new System.Timers.Timer();
protected override void OnStart(string[] args)
{
myWorkingThread = new System.Threading.Thread(PrepareTask);
myWorkingThread.Start();
}
private void PrepareTask()
{
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Interval = 60000;
myTimer.Start();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
..my code to prepare binary db files
BinaryDB rdr = new BinaryDB();
rdr.ReadFile(...)
}
}
It is because the timer interval is set to 1 minute. See the below code in PrepareTask
myTimer.Interval = 60000;
You can set it to any appropriate value. or if you want your code to return once at the start and then after every 60 seconds than you should call it once in OnStart method. Like
protected override void OnStart(string[] args)
{
// Do other initialization stuff...
EvalutateChangeConditions ();
// Create the thread and tell it what is to be executed.
myWorkingThread = new System.Threading.Thread(PrepareTask);
// Start the thread.
myWorkingThread.Start();
}
I'm trying to create a Windows Form application that searches for a string and has three possible scenarios:
String 1 found - wait
String 2 found - stop
Else - Perform action and wait 1 minute
I am encountering my problem only on the times when it is expected to wait. When this happens, the newTimer_Tick starts to tick every second. I have tried disabling the timer when it ticks and a few other things but none appeared to work. Below is the code:
public void Action(string result)
{
if (result.Contains("string1"))
{
// Check again in 10 + x seconds
int n = new Random().Next(0, 5000);
int newtime = 10000 + n;
newTimer.Tick += new EventHandler(newTimer_Tick);
newTimer.Interval = newtime;
newTimer.Enabled = true;
}
else if (result.Contains("string2"))
{
// Turn off
newTimer.Enabled = false;
}
else
{
// Perform action and tick again in 1min + x seconds
action1();
int n = new Random().Next(0, 5000);
int newtime = 600000 + n;
newTimer.Tick += new EventHandler(newTimer_Tick);
newTimer.Interval = newtime;
newTimer.Enabled = true;
}
}
private void newTimer_Tick(object sender, EventArgs e)
{
Action( result );
}
What have I done wrong?
Each time the following line is called, an new instance of the event handler newTimerTick is added to the invocation list for the Tick event:
newTimer.Tick += new System.EventHandler(newTimer_Tick);
So every time the time tick goes off newTimerTick is going to be called multiple times, which is going to give you unexpected results.
Configure your event handler once only. In the constructor would be a sensible place.
Have you tried to stop the timer with the Timer.Stop method?
Btw: I don't think you need to reassign the Tick event from the newTimer unless you don't create a new Timer everytime.
I think what you were missing is that you have to stop your timer since you don't actually want it to keep for more than one interval. You seem to want to run it once, check on the result and then decide if you want to keep running it or not. Here's the code:
public void action(string result)
{
int n = new Random().Next(0, 5000);
Boolean blActivateTimer = true;
Timer timer = new Timer();
timer.Tick += timer_Tick;
if (!result.Contains("string1") && !result.Contains("string2"))
{
n += 600000;
action1();
}
else
{
if (result.Contains("string1"))
{
n += 10000;
}
else
{
blActivateTimer = false;
}
}
if (blActivateTimer)
{
timer.Start();
}
}
void action1()
{
}
void timer_Tick(object sender, EventArgs e)
{
Timer t = (Timer)sender;
t.Stop();
action(result);
}
I am having a problem get code to run through a system timer on a service , well actually no the timer IS firing , however the code below it will not run.
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("Service Started");
//ad 1: handle Elapsed event
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
//ad 2: set interval to 1 minute (= 60,000 milliseconds)
timer.Interval = 60000;
timer.AutoReset = true;
//ad 3: enabling the timer
timer.Enabled = true;
}
protected override void OnStop()
{
timer.Enabled = false;
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
EventLog.WriteEntry("TIMER FIRED");
string[] filepaths = Directory.GetFiles(path, Filetype);
string result;
// Process Each String/File In Directory
foreach (string s in filepaths)
{
for (int i = 0; i < filepaths.Length; i++)
{
//Result Returns Video Name
result = Path.GetFileNameWithoutExtension(filepaths[i]);
PreformTranslation(filepaths[i], outputPath + result);
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
}
}
}
So i See from the event viewer that it actually sends the "timer Fired" off each minute , but does not precede to run any of the code below. Without the timer in place the code runs as it should, so inititally i just tried calling the method, when that didn't work i just placed the code in the event handler hoping that would change. I think I've already lost when i resort to hope.