I've following code snippet for windows service and it is not hitting timer1_Elapsed which is the main function to execute my logic. I've gone through the code using debugging. I would like to seek suggestions from experts.
public partial class myService : ServiceBase
{
public myService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("myService Source"))
{
System.Diagnostics.EventLog.CreateEventSource(
"myService Source", "myService Log");
}
eventLog1.Source = "myService Source";
eventLog1.Log = "myService Log";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("myService service started on " + DateTime.Now.ToString());
System.Diagnostics.Debugger.Launch();
System.Diagnostics.Debugger.Launch();
string ProcessHour = ConfigurationManager.AppSettings["ProcessHour"];
int intProcessHour = Convert.ToInt32(ProcessHour);
DateTime dtNow = DateTime.Now;
if (dtNow.Hour < intProcessHour)
{
DateTime dtToday = DateTime.Today;
DateTime dtStartDateTime = dtToday.AddHours(Convert.ToDouble(ProcessHour));
System.TimeSpan diff = dtStartDateTime.Subtract(DateTime.Now);
timer1.Interval = diff.TotalMilliseconds;
timer1.Start();
}
else
{
DateTime dtToday = DateTime.Today;
DateTime dtStartDateTime = dtToday.AddDays(1).AddHours(Convert.ToDouble(ProcessHour));
System.TimeSpan diff = dtStartDateTime.Subtract(DateTime.Now);
timer1.Interval = diff.TotalMilliseconds;
timer1.Start();
}
}
protected override void OnStop()
{
eventLog1.WriteEntry("myService service stopped on " + DateTime.Now.ToString());
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
timer1.Stop();
string StartTimer, EndTimer;
StartTimer = DateTime.Now.ToString();
eventLog1.WriteEntry("myService timer1_Elapsed begin on " + DateTime.Now.ToString());
/*Some Logic*/
}
catch (Exception ex)
{
}
}
}
Edit
InitializeComponent() does contain that function but still unable to make a hit.
private void InitializeComponent()
{
this.eventLog1 = new System.Diagnostics.EventLog();
this.timer1 = new System.Timers.Timer();
((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 60000;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
//
// myService
//
this.ServiceName = "myService";
((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();
}
Unless you did it in the designer (so maybe it's into InitializeComponent()), you seem like you're missing to attach the event to timer1
timer1.Tick += timer1_Elapsed;
This should make the code work like you expect
If even this doesn't work, consider using the class System.Timers.Timer. Here's a reference that might help you understand the differences between Timer classes
https://web.archive.org/web/20150329101415/https://msdn.microsoft.com/en-us/magazine/cc164015.aspx
Related
I am newbie to windows service and following is what I am trying. The System.Timers.Timer timer1_Elapsedget fired only when I am debugging but when I went for installation nothing get happen. I don't think if I am missing but still I would like to have suggestion/advice from experts and gurus.
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("myTestService service started on " + DateTime.Now.ToString());
//System.Diagnostics.Debugger.Launch();
double processHour = Convert.ToDouble(ConfigurationManager.AppSettings["ProcessHour"]);
DateTime dtStartDateTime = DateTime.Today.AddHours(processHour);
DateTime dtNow = DateTime.Now;
if (dtNow.Hour>= processHour)
{
dtStartDateTime = dtStartDateTime.AddDays(1);
}
System.TimeSpan diff = dtStartDateTime.Subtract(dtNow);
timer1.Interval = diff.TotalMilliseconds;
this.timer1.Elapsed += timer1_Elapsed;
this.timer1.Start();
eventLog1.WriteEntry("myTestService service exit from onStart at" + DateTime.Now.ToString());
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
eventLog1.WriteEntry("myTestService timer1_Elapsed begin on " + DateTime.Now.ToString());
/*some logic*/
}
I'm writing Windows Service that calls for method after defined period of time (for now its 20 seconds). Everything was working fine until it didn't. Can't seem to find the cause of the problem.
Service seems to start and stop properly giving log entry, but it seems like it doesnt call for elapsed event.
public partial class UssPwdSyncService : ServiceBase
{
private Timer timer1 = null;
public UssPwdSyncService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
timer1 = new Timer();
this.timer1.Interval = 20000;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_tick);
timer1.Enabled = true;
LogHandling.WriteErrorLogs("Service has started! LOg!");
}
catch (Exception ex)
{
LogHandling.WriteErrorLogs(ex);
}
}
private void timer1_tick(object sender, ElapsedEventArgs e)
{
ConfigurationManager.RefreshSection("connectionStrings");
foreach (ConnectionStringSettings cStr in ConfigurationManager.ConnectionStrings)
{
string name = cStr.Name;
string connString = cStr.ConnectionString;
string provider = cStr.ProviderName;
LogHandling.WriteErrorLogs(name + " " + connString + " " + provider);
}
LogHandling.WriteErrorLogs("This does something!");
}
protected override void OnStop()
{
timer1.Enabled = false;
LogHandling.WriteErrorLogs("Service has stoped!");
}
}
Could someone point out what am I missing?
I moved try catch to timer1_tick method.
This is the right place to exception check.
You can be throwing an exception o timer1_tick peace of code.
You have connectionStrings sections?
Note: i prefer to use Start and Stop methods instead of Enabled = true
and Enabled = false.
Two ways are right.
Try this:
public partial class UssPwdSyncService : ServiceBase
{
private Timer timer1 = null;
public UssPwdSyncService()
{
InitializeComponent();
this.timer1 = new Timer();
this.timer1.Interval = 20000;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_tick);
}
protected override void OnStart(string[] args)
{
this.timer1.Start();
LogHandling.WriteErrorLogs("Service has started! LOg!");
}
private void timer1_tick(object sender, ElapsedEventArgs e)
{
try
{
ConfigurationManager.RefreshSection("connectionStrings");
foreach (ConnectionStringSettings cStr in ConfigurationManager.ConnectionStrings)
{
string name = cStr.Name;
string connString = cStr.ConnectionString;
string provider = cStr.ProviderName;
LogHandling.WriteErrorLogs(name + " " + connString + " " + provider);
}
LogHandling.WriteErrorLogs("This does something!");
}
catch (Exception ex)
{
LogHandling.WriteErrorLogs(ex);
}
}
protected override void OnStop()
{
this.timer1.Stop();
LogHandling.WriteErrorLogs("Service has stoped!");
}
}
I assume you're using the Timer in System.Timers. You need to call the timer's Start() method.
I can't get the timer to tick every time when i create a new command object I am wondering what is causing this. I am new to C# so if i could get help as to why this is happening it would be greatly appreciated.
This should trigger, but doesnt
command Cmd = new command("!example", 10);
Here's the code.
public class Timeout
{
public Timeout() { }
public static List<command> timeouts = new List<command>();
public class command
{
public string cmd;
public int seconds;
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { Interval = 1000 };
public command(string cmd, int seconds)
{
Debug.WriteLine("created, " + cmd + ", " + seconds);
this.cmd = cmd;
this.seconds = seconds;
this.timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
Debug.WriteLine("tick -> " + seconds);
if (seconds > 0)
seconds--;
else
{
timer.Tick -= Timer_Tick;
timeouts.Remove(this);
Debug.WriteLine("removed");
}
}
}
}
actually you can do this way.
call the timer once you create the object
command cmd =new command("!example",10);
//then am calling the timer event
timer = new Timer(3000); // Set up the timer for 3 seconds
timer.Elapsed += new ElapsedEventHandler(timerElapsed);
//_timer_Elapsed is the event name
timer.Enabled = true;
public static void timerElapsed(object sender, ElapsedEventArgs e)
{
//do something here
}
please find the link here for more reference.hope my comment helps you :)
I'am trying to create watch folder aplicaction in C# that will do an action when new file will arrive. Since the watched folder is on GPFS share I'am unable to use FileSystemWatcher (which works fine for me in NTFS). So I've based the app on other collegue solution.
The app shows nicely "Timer starts" message but when it comes to
timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
it did not calls the DoStuff method - "Starting new files proc" message never show up. What I've done wrong? Here is complete code:
namespace MonitorFolderActivity
{
public partial class frmMain : Form
{
List<string> fileList = new List<string>();
System.Timers.Timer timer;
DateTime LastChecked;
public frmMain()
{
InitializeComponent();
}
private void abortAcitivityMonitoring()
{
btnStart_Stop.Text = "Start";
txtActivity.Focus();
}
private void startActivityMonitoring(string sPath)
{
if (sPath.Length < 3)
{
MessageBox.Show("You have to enter a folder to monitor.",
"Hey..!", MessageBoxButtons.OK, MessageBoxIcon.Stop);
abortAcitivityMonitoring();
}
else
{
TS_AddLogText(string.Format("Timer starts\r\n"));
timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
}
}
private void stopActivityMonitoring()
{
TS_AddLogText(string.Format("Timer stops\r\n"));
this.timer.Stop();
}
private void DoStuff(object sender, System.Timers.ElapsedEventArgs e)
{
TS_AddLogText(string.Format("Starting new files proc\r\n"));
LastChecked = DateTime.Now;
string[] files = System.IO.Directory.GetFiles("D:\\MEDIAIN\\", "*", System.IO.SearchOption.AllDirectories);
foreach (string file in files)
{
if (!fileList.Contains(file))
{
fileList.Add(file);
TS_AddLogText(string.Format(file));
}
}
TimeSpan ts = DateTime.Now.Subtract(LastChecked);
TimeSpan MaxWaitTime = TimeSpan.FromMinutes(1);
if (MaxWaitTime.Subtract(ts).CompareTo(TimeSpan.Zero) > -1)
timer.Interval = MaxWaitTime.Subtract(ts).TotalMilliseconds;
else
timer.Interval = 1;
timer.Start();
}
private delegate void AddLogText(string text);
private void TS_AddLogText(string text)
{
if (this.InvokeRequired)
{
AddLogText del = new AddLogText(TS_AddLogText);
Invoke(del, text);
}
else
{
txtActivity.Text += text;
}
}
private void btnStart_Stop_Click(object sender, EventArgs e)
{
if (btnStart_Stop.Text.Equals("Start"))
{
btnStart_Stop.Text = "Stop";
startActivityMonitoring(txtFolderPath.Text);
}
else
{
btnStart_Stop.Text = "Start";
stopActivityMonitoring();
}
}
private void lblActivity_Click(object sender, EventArgs e)
{
}
private void lblToMonitor_Click(object sender, EventArgs e)
{
}
}
}
There are few issues in your code.
First of all you are not setting the time at which timer should elapse, which means it will read the default value which is
100 ms
Secondly you are not starting your timer. You need to add this line to your code in this method startActivityMonitoring else statement.
timer.Interval = yourdesiredinterval;
timer.Start();
Thirdly, as you are doing stop and start (by looks of your code) you should not create a new timer on each call of your startActivityMonitoring method. Rather you should do this
If(timer == null)
{
timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Interval = yourinterval;
timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
}
timer.Start();
In your else clause, you never start the timer. Here's a fix:
else
{
TS_AddLogText(string.Format("Timer starts\r\n"));
timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
timer.Start();
}
I have created a windows service with timer in c#.net. it works fine while i debug/build the project in visual studio but it does not perform its operation after installation.
What might be the reason behind this ?
code :
public partial class Service1 : ServiceBase
{
FileStream fs;
StreamWriter m_streamWriter;
Timer tm = new Timer();
public Service1()
{
InitializeComponent();
this.ServiceName = "timerservice";
tm.Interval = 2000;
tm.Tick += new EventHandler(PerformOperations);
tm.Start();
fs = new FileStream(#"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write);
m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
}
private void PerformOperations(object sener, EventArgs e)
{
//StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true);
try
{
OdbcConnection con = new OdbcConnection("DSN=liquor_data");
OdbcDataAdapter adp = new OdbcDataAdapter("", con);
DataSet ds = new DataSet();
string sql = "select * from item_group";
adp.SelectCommand.CommandText = sql;
adp.Fill(ds, "item_group");
foreach (DataRow dr in ds.Tables["item_group"].Rows)
{
// swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
//Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
}
m_streamWriter.Flush();
}
catch (Exception ex)
{
// swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); }
}
}
}
First approach with Windows Service is not easy..
A long time ago, I wrote a C# service.
This is the logic of the Service class (tested, works fine):
namespace MyServiceApp
{
public class MyService : ServiceBase
{
private System.Timers.Timer timer;
protected override void OnStart(string[] args)
{
this.timer = new System.Timers.Timer(30000D); // 30000 milliseconds = 30 seconds
this.timer.AutoReset = true;
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
this.timer.Start();
}
protected override void OnStop()
{
this.timer.Stop();
this.timer = null;
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MyServiceApp.ServiceWork.Main(); // my separate static method for do work
}
public MyService()
{
this.ServiceName = "MyService";
}
// service entry point
static void Main()
{
System.ServiceProcess.ServiceBase.Run(new MyService());
}
}
}
I recommend you write your real service work in a separate static method (why not, in a console application...just add reference to it), to simplify debugging and clean service code.
Make sure the interval is enough, and write in log ONLY in OnStart and OnStop overrides.
Hope this helps!
You need to put your main code on the OnStart method.
This other SO answer of mine might help.
You will need to put some code to enable debugging within visual-studio while maintaining your application valid as a windows-service. This other SO thread cover the issue of debugging a windows-service.
EDIT:
Please see also the documentation available here for the OnStart method at the MSDN where one can read this:
Do not use the constructor to perform processing that should be in
OnStart. Use OnStart to handle all initialization of your service. The
constructor is called when the application's executable runs, not when
the service runs. The executable runs before OnStart. When you
continue, for example, the constructor is not called again because the
SCM already holds the object in memory. If OnStop releases resources
allocated in the constructor rather than in OnStart, the needed
resources would not be created again the second time the service is
called.
Here's a working example in which the execution of the service is started in the OnTimedEvent of the Timer which is implemented as delegate in the ServiceBase class and the Timer logic is encapsulated in a method called SetupProcessingTimer():
public partial class MyServiceProject: ServiceBase
{
private Timer _timer;
public MyServiceProject()
{
InitializeComponent();
}
private void SetupProcessingTimer()
{
_timer = new Timer();
_timer.AutoReset = true;
double interval = Settings.Default.Interval;
_timer.Interval = interval * 60000;
_timer.Enabled = true;
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
// begin your service work
MakeSomething();
}
protected override void OnStart(string[] args)
{
SetupProcessingTimer();
}
...
}
The Interval is defined in app.config in minutes:
<userSettings>
<MyProject.Properties.Settings>
<setting name="Interval" serializeAs="String">
<value>1</value>
</setting>
</MyProject.Properties.Settings>
</userSettings>