I wrote a windows service to call my class library every 10 mins interval,it works fine when start or restart .once the job done it suppose to re run again every 10 min's that's not happening at all.Am not sure what am missing,some one please identify the correct way.
Here is my code
public partial class Service1 : ServiceBase
{
private Timer _timer;
private DateTime _lastRun = DateTime.Now;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
_timer = new Timer(10 * 60 * 1000); // every 10 minutes
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
Shell Distribute= new Shell();
Distribute.Distribute();
}
protected override void OnStop()
{
this.ExitCode = 0;
base.OnStop();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//if (_lastRun.Date < DateTime.Now.Date)
//{
_timer.Stop();
_lastRun = DateTime.Now;
_timer.Start();
//}
}
}
}
Your problem is compare of date if (_lastRun.Date < DateTime.Now.Date) so your code runs once a day.
I agree with Ozgur. It appears that your logic is wrong. You can just stop the timer during the timer_Elapsed event do you logic and restart timers
Something like :
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try{
// stop the timer while we are running the cleanup task
_timer.Stop();
//
// do cleanup stuff
//
}catch (Exception e){
//do your error handling here.
}
finally{
_timer.Start();
}
}
}
Just wrap it with a try catch and finally so you handle exceptions and can make sure the timer is started again. Also please review this link Best Timer for using in a Windows service
Okie Finally i got the answer,why its not working (One of the expert from other forum point out my mistake)
This the code works well based on timer interval.
public partial class Service1 : ServiceBase
{
private Timer _timer;
private DateTime _lastRun = DateTime.Now;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
_timer = new Timer(10 * 60 * 1000); // every 10 minutes
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
Shell Distribute= new Shell();
Distribute.Distribute();
_timer.start();//this line was missed in my original code
}
protected override void OnStop()
{
this.ExitCode = 0;
base.OnStop();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//if (_lastRun.Date < DateTime.Now.Date)
//{
try
{
_timer.Stop();
Shell Distribute= new Shell();
Distribute.Distribute();
}
catch(exception ex)
{}
finally
{
_timer.Start();
}
//}
}
}
}
Related
My service is running but it does not do any of the logic i inserted in OnStart,
Also, I am try to log messages to the eventviewer but it does not even get to that part (which i assume is falling before the OnStart..)
Can someone please tell me what i am doing wrong? Thanks,
public partial class DSGService : ServiceBase
{
private static string ftpPath = ConfigurationManager.AppSettings["FtpPath"];
private Timer _timer;
private bool _isRunning;
public DSGService()
{
InitializeComponent();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
WriteToEventViewer("error!:" + e.ExceptionObject.ToString());
}
OnStart logic
protected override void OnStart(string[] args)
{
_isRunning = false;
_timer = new Timer
{
AutoReset = true,
Interval = 5000,
};
_timer.Elapsed += new ElapsedEventHandler(this.TimerElapsed);
_timer.Start();
}
code to do things
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
if (_isRunning)
{
WriteToEventViewer("isrunning is true");
return;
}
try
{
_isRunning = true;
WriteToEventViewer("started");
//do things..
WriteToEventViewer("generated!");
}
}
finally
{
_isRunning = false;
WriteToEventViewer("done");
}
}
private void GenerateAndPublishData(ServerData server)
{
try
{
//do things...
}
catch (Exception ee)
{
WriteToEventViewer(string.Format("error: {0}", ee);
}
}
protected override void OnStop()
{
_timer.Stop();
_timer.Dispose();
_timer = null;
}
write to eventviewer
private void WriteToEventViewer(string msg)
{
using (EventLog eventLog = new EventLog("DSGService"))
{
eventLog.Source = "DSGService";
eventLog.WriteEntry(msg, EventLogEntryType.Information, 101, 1);
}
}
}```
This is probably the result of an exception inside the TimerElapsed method, that prevents the timer from restarting. To aviod this, here's what you do:
Set the AutoReset property of your timer to false.
Inside the TimerElapsed event handler, in the finally clause, start the timer again.
This means that even if an exception occured in your TimerElapsed event handler, the timer will start again.
I have windows service application. But the OnStart event does not fire. Only OnStop event is firing every time I stop the service. What did I miss ?
public partial class Scheduler : ServiceBase
{
private Timer timer1 = null;
public Scheduler()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1 = new Timer();
timer1.Interval = 5000;
timer1.Elapsed += new ElapsedEventHandler(this.timer1_Tick);
}
protected override void OnStop()
{
timer1.Enabled = false;
Library.Log(String.Format("Windows service stopped"));
}
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
Library.Log(String.Format("Scheduler service {0}", DateTime.Now));
}
}
OnStart is firing, your timer is not.
You must either do timer1.Start() or timer1.Enabled = true in OnStart for the timer to start firing.
protected override void OnStart(string[] args)
{
Library.Log("Windows service started");
timer1 = new Timer();
timer1.Interval = 5000;
timer1.Elapsed += new ElapsedEventHandler(this.timer1_Tick);
timer1.Start()
}
I'm currently trying to create a service that will execute a metod every 14 days, (is 20 sec now, becasue of testing). I have currently these lines of code in my service and i cant seem to get it to run the AddDataToDb() metod. Anyone got any idea of what i can do to get the timer to work?
public partial class Service1 : ServiceBase
{
System.Timers.Timer oTimer = null;
double interval = 2000;
public Service1()
{
InitializeComponent();
IntializeService();
}
void IntializeService()
{
oTimer = new System.Timers.Timer(interval);
oTimer.Enabled = true;
oTimer.AutoReset = true;
oTimer.Start();
oTimer.Elapsed += new ElapsedEventHandler(oTimer_Elapsed);
}
void oTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Data.mData data = new mData();
data.AddDataToDb();
}
protected override void OnStart(string[] args)
{
oTimer.Enabled = true;
oTimer.Start();
}
protected override void OnStop()
{
oTimer.Stop();
}
}
I do have one checking function that will run once opening the application.
How to make it Auto Function like every 20 seconds run the function?
Main()
{
Checking();
}
public void Checking() // run this function every 20 seconds
{ // some code here
}
You can use the C# Timer class
public void Main()
{
var myTimer = new Timer(20000);
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Enabled = true;
Console.ReadLine();
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
Main()
{
Timer tm = new Timer();
tm.Interval = 20000;//Milliseconds
tm.Tick += new EventHandler(tm_Tick);
tm.Start();
}
void tm_Tick(object sender, EventArgs e)
{
Checking();
}
public void Checking()
{
// Your code
}
I would like handle the occurred System.Timers.Timer elapsed exception (in my DLL library) within my WPF application. But I'm not be able to do that. It throws in my DLL library and the application will crashing...
Does anybody know how I can solve the problem?
Here my code:
public partial class MainWindow : Window
{
MyClass _myClassInstance = null;
public MainWindow()
{
InitializeComponent();
try
{
_myClassInstance = new MyClass();
}
catch(Exception ex)
{
//Here i would like to receive the exception
//But it never goes in there
MessageBox.Show(ex.Message);
}
}
}
public class MyClass
{
private System.Timers.Timer _timer = null;
public MyClass()
{
_timer = new Timer();
_timer.Interval = 2000; //2 Seconds
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
ConnectTo();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//If timer is elapsed I have to raise an exception
throw new Exception("It's taking longer than expected. Progress cancelled!");
}
private void ConnectTo()
{
//Just an example implementation
//Do something!!
//Connect to SerialPort and wait for correct response
//If connected than
_timer.Stop();
}
}
The exception is thrown on another thread (as per your choice for Timing.Timer).
Try this inside 1 assembly: you can't catch it either. That it's in a DLL doesn't matter.
You can only solve this by re-thinking the problem and picking another solution.
The exception is happening inside the event. This is run on another thread, therefore it's never going to make it back to your original thread.
Two possibilities to do this differently.
Your serial port com library has some sort of timeout functionality (maybe), just use it instead.
Do your serial port checking on a separate tread. If your time runs out, kill that thread.
public class MyClass
{
private System.Timers.Timer _timer = null;
private Thread t;
public MyClass()
{
_timer = new Timer();
_timer.Interval = 2000; //2 Seconds
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
t = new Thread(new ThreadStart(ConnectTo));
t.Start();
t.Join();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//If timer is elapsed I have to raise an exception
if (t != null)
t.Abort();
}
private void ConnectTo()
{
//Just an example implementation
//Do something!!
//Connect to SerialPort and wait for correct response
//If connected than
_timer.Stop();
}
}
As an alternative approach, rather trying to control your application flow with Exceptions, you could use events instead e.g.
public partial class MainWindow : Window
{
MyClass _myClassInstance = null;
public MainWindow()
{
InitializeComponent();
_myClassInstance = new MyClass();
_myClassInstance.TimedOut += delegate (object sender, EventArgs e) {
((MyClass)sender).CancelConnect();
MessageBox.Show("Timeout!");
};
_myClassInstance.ConnectTo();
}
}
...
public class MyClass
{
Timer _timer = new Timer();
public event EventHandler TimedOut;
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
OnTimedOut();
}
private void OnTimedOut()
{
var handler = TimedOut;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
public void ConnectTo(int timeout = 2000)
{
CancelConnect();
_timer.Interval = timeout; // pass timeout in so it's flexible
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
// do connect stuff...
_timer.Stop();
}
public void CancelConnect()
{
_timer.Stop();
// cancel connect stuff...
}
}
I think you had far too much going on in your constructor for MyClass so I moved it into ConnectTo which you invoke directly from your MainWindow.
Not work:
MessageBox.Show(e.Message); doen's throw
public class MyClass
{
private System.Timers.Timer _timer = null;
private Thread t;
public MyClass()
{
try
{
_timer = new System.Timers.Timer();
_timer.Interval = 5000; //2 Seconds
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
t = new Thread(new ThreadStart(ConnectTo));
t.Start();
t.Join();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//If timer is elapsed I have to raise an exception
if (t != null)
{
t.Abort();
}
}
private void ConnectTo()
{
//Just an example implementation
//Do something!!
try
{
//Connect to SerialPort and wait for correct response
using (SqlConnection _SC = new SqlConnection("aaaa"))
{
_SC.Open();
}
}
catch (Exception)
{
throw;
}
finally
{
//If connected than
_timer.Stop();
}
}
}