i'm facing a strange problem with a Timer in a Windows service. is my first windows service, so for start to learn i decide to create a service that each 10 seconds write in a .txt file what time is it.
i add the timer but looks like the timer never start.
can you help me to understand where i'm wrong?
here my code:
namespace testtimer
{
public partial class TestTimer : ServiceBase
{
public TestTimer()
{
InitializeComponent();
timer.Interval = 10000;
timer.Enabled = true;
}
protected override void OnStart(string[] args)
{
timer.Start();
}
protected override void OnStop()
{
}
private void timer_Tick(object sender, EventArgs e)
{
string date = System.DateTime.Now.ToString();
StreamWriter wr = new StreamWriter(#"C:\Users\xxx\Desktop\Test\testtimer.txt", true);
wr.WriteLine("\n" + "The Time is:" + "\t" + date);
wr.Close();
}
}
}
where i'm wrong?
thanks a lot for your help :)
Am guessing you are using a Windows.Forms timer (the component one, that you drag onto your design surface)....this needs a "window" and "message loop" in order to be able to process/receive the actual timer tick event.
When you're an NT service....you don't have a window...you're just a bit of code that has entry points that get called by the SCM (Service Control Manager).
You need to use a different type of timer that uses a thread, and will call back a function.
Best Timer for using in a Windows service
Related
I'm pretty new in c# and I'm programing just for my personal studies, I have been trying to program an instruction where a read some data from a remote station to my application (m64...mw74), it's running OK for couple minutes but its crash maybe after 5 minutes.
please see the code I'm using below to update my data every 1 second and write it in a simple text box in my form.enter image description here
Thank you very much in advance.
private void Load_act()
{
actvalueL1.Text = plc.Read("mw64").ToString();
actvaluep1.Text = plc.Read("mw68").ToString();
actvaluep2.Text = plc.Read("mw71").ToString();
actvaluep3.Text = plc.Read("mw74").ToString();
InitTimer();
}
private Timer timer1;
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // in miliseconds
timer1.Start();
//Console.ReadLine();
}
private void timer1_Tick(object sender, EventArgs e)
{
Load_act();
}
You're chaining the timers, eventually going to run yourself out of memory as they cannot dispose - the timer creates the next with its own call. Return them on to a parent method that loops your timer 'initTimer'
I need a timer that executes every minute but i have trouble getting the timer to run at all with code that i used before. so i guess i am doing sth fundamentally wrong that is not code related but even in a just newly created Console project in visual studio community 2017 it doesn't execute the _timer_elapsed method. the console terminates immediately without errors as if it has executed every code
using System;
using System.Timers;
namespace Test
{
class Program
{
static Timer _timer;
public static void Main(string[] args)
{
var timer = new Timer(60000);
timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
timer.Enabled = true;
_timer = timer;
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("test");
}
}
}
what am I missing here?
You need your program to stay alive, rather than return from Main. An quick and easy way to do this is to wait for some input at the end:
public static void Main(string[] args)
{
var timer = new Timer(60000);
timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
timer.Enabled = true;
_timer = timer;
Console.ReadLine();
}
There is no such thing as a bad question.
(Though some questions show more affinity with programming, and some show less.)
If you look at your code, your main sets up a timer and then proceeds to terminate. So, of course your program exits immediately and the timer is never fired.
In order to see your timer firing, your program will need to keep running for at least as long as one period of your timer.
I have a method that executes in about 10 minutes. And it goes well just by itself. I need to start this method every hour using windows service (this is obligatory). So I've written my service by some examples (just one invoke for start):
partial class ServiceWSDRun : ServiceBase
{
protected override void OnStart(string[] args)
{
Thread t = new Thread(WebServiceDownload.MainProgram.Execute);
t.Start();
}
}
Now when I install it, it launches my method in a new thread but this thread seem to end with the OnStart() - it actually logs some info from the beginning of me method. Why does it stop and what should I do?
And I'm thinking in the end I should have something like this:
partial class ServiceWSDRun : ServiceBase
{
System.Timers.Timer timer = null;
protected override void OnStart(string[] args)
{
Thread t = new Thread(WebServiceDownload.MainProgram.Execute);
t.Start();
timer = new System.Timers.Timer();
timer.Interval = 60 * 60 * 1000; // 1 hour
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer);
timer.Enabled = true;
}
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
WebServiceDownload.MainProgram.Execute();
}
protected override void OnStop()
{
timer.Enabled = false;
}
}
How do I make it work? And keep in mind that method takes ~10 mins to execute.
You should use System.Threading.Timer instead of System.Timers.Timer.
Here is the reference for this:
https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx
Also, another thread about the same topic:
System.Timers.Timer vs System.Threading.Timer
You should lock the execution, avoiding the second execution before the first one finishes.
I have a C# program that is constantly checking for new additions to an online DB. I have this code to have it check every 10 seconds
static void Main(string[] args)
{
boolean run = true;
while (run)
{
DBConnect Db = new DBConnect();
// do amazing awesome mind blowing cool stuff
Db.closeConnection();
// wait for 10 seconds
int wait = 10 * 1000;
System.Threading.Thread.Sleep(wait);
}
}
i have error reporting that posts to the DB and if a major error occurs the program shuts down. Outside of the specific errors within my function, is this method secure and efficient?
You should rewrite your program as a windows service, that way you do not need to rely on a user to be logged for your program to run.
If you do go with the service route, I would swap out the infinite loop for a timer.
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
int wait = 10 * 1000;
timer = new Timer(wait);
timer.Elapsed += timer_Elapsed;
// We don't want the timer to start ticking again till we tell it to.
timer.AutoReset = false;
}
private System.Timers.Timer timer;
protected override void OnStart(string[] args)
{
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
DBConnect Db = new DBConnect())
try
{
// do amazing awesome mind blowing cool stuff
}
finally
{
Db.closeConnection(); //We put this in a finally block so it will still happen, even if an exception is thrown.
}
timer.Start();
}
catch(SomeNonCriticalException ex)
{
MyExecptionLogger.Log(ex, Level.Waring); //Log the exception so you know what went wrong
timer.Start(); //Start the timer for the next loop
}
catch(Exception ex)
{
MyExecptionLogger.Log(ex, Level.Critical); //Log the exception so you know what went wrong
this.Stop(); //Stop the service
}
}
protected override void OnStop()
{
timer.Stop();
}
}
Write it as a console program without the wait and set up a scheduled task to run it periodically. You want to run it every 10 seconds? Every minute? Just change the scheduled task.
You can use the Task Scheduler GUI, or the schtasks command line tool.
See Programs are not cats.
I would setup a windows service and use SqlDependency http://msdn.microsoft.com/en-CA/library/a52dhwx7(v=vs.80).aspx. That way when a change (which you specify) occurs in the database, it will trigger the OnChange event which you specify to do whatever it is you need to do. See the link for implementation details.
I am trying to have a Windows service run all the time in the background of my computer with no-one knowing. My Windows service downloads the content of my email inbox and puts it in my database.
My Windows service just seams to stop - it enters a log every 60 seconds and then stops about 10 mins in?
I have posted my code below. Can any one see or tell me a reason why?
Any help would be much appreciated.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace EmailWindowsService
{
public partial class MyEmailService : ServiceBase
{
private DateTime lastRun;
private bool flag = true;
private static System.Timers.Timer aTimer;
public MyEmailService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource")) // every thing the windows service does is logged in server explorer
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog");
}
eventLogEmail.Source = "MySource";
eventLogEmail.Log = "MyNewLog";
// Timer Code
aTimer = new System.Timers.Timer(1 * 60 * 1000); // 60 seconds
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Enabled = true;
// Timer Code
}
protected override void OnStart(string[] args)
{
flag = true;
lastRun = DateTime.Now;
eventLogEmail.WriteEntry("Started");
}
protected override void OnStop()
{
eventLogEmail.WriteEntry("Stopped");
}
protected override void OnPause()
{
eventLogEmail.WriteEntry("Paused");
}
protected override void OnContinue()
{
eventLogEmail.WriteEntry("Continuing");
}
protected override void OnShutdown()
{
eventLogEmail.WriteEntry("ShutDowned");
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
RetriveEmailClass Emails = new RetriveEmailClass();
if (flag == true)
{
eventLogEmail.WriteEntry("In getting Email Method");
Emails.ServiceEmailMethod();
lastRun = DateTime.Now;
flag = false;
}
else if (flag == false)
{
if (lastRun.Date < DateTime.Now.Date)
{
Emails.ServiceEmailMethod();
eventLogEmail.WriteEntry("In getting Email Method");
}
}
}
}
}
See that your class has no errors, an error there could throw you whole service out.
Also try putting your timer into a method and only call it, not have it in your service code.
A windows service should always be made as an empty shell that just call's methods.
Couple of reasons that your Windows services stops running.
1. Unhandled exception in your code. Looking from you code snippet, please add exception handling in the OnTimedEvent() method.
2. You service may crashed for some reason. In this case, you can go to event viewer to find out the reason for the failure.
Hope this helps.
You most likely have an unhandled exception. It's hidden since you use System.Timers.Timer. That timer eats all unhandled exceptions instead of letting them crash your app.
That means that your app might look like it's running OK while it's not. A try/catch in the timer callback will prove that.
I do recommend that you use System.Threading.Timer instead since it do not work in that way.
Your code is straightforward enough except the source for your Emails.ServiceEmailMethod method. Does the method generate any exceptions? If so, they have not been trapped in your timer method. Try:
try { Emails.ServiceEmailMethod(); }
catch (Exception ex) { eventLogEmail.WriteEntry(ex.Message); }