Window service : How to start a Timer at Particular Time - c#

I have seen similar post of setting Timer at particular time ... I Dont want to run timer Whole Day ...I Want to start it at specific Time ..
Most of the suggestion is use Scheduled tasks ...but I want to do it with window service ....
Here is My Service Working Code :
public AutoSMSService2()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog");
}
eventLog1.Source = "MySource";
eventLog1.Log = "MyNewLog";
Timer checkForTime = new Timer(5000);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart");
}
protected override void OnStop()
{
eventLog1.WriteEntry("In onStop.");
}
void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
eventLog1.WriteEntry("Timer Entry");
}
My Timer is working fine and adding Log at 5 sec interval ..But I want to start Timer Lets Say 3:00 PM ...
private static void SetTimer(Timer timer, DateTime due)
{
var ts = due - DateTime.Now;
timer.Interval = ts.TotalMilliseconds;
timer.AutoReset = false;
timer.Start();
}
But I am not sure How to Implement it in Code ..
Any suggestion would be Helpful

If you want to do it every day, Hope this will help.
private System.Threading.Timer myTimer;
private void SetTimerValue ()
{
DateTime requiredTime = DateTime.Today.AddHours(15).AddMinutes(00);
if (DateTime.Now > requiredTime)
{
requiredTime = requiredTime.AddDays(1);
}
myTimer = new System.Threading.Timer(new TimerCallback(TimerAction));
myTimer.Change((int)(requiredTime - DateTime.Now).TotalMilliseconds, Timeout.Infinite);
}
private void TimerAction(object e)
{
//here you can start your timer!!
}

here an example with windows form but you can achieve the some thing with windows service
public partial class Form1 : Form
{
private bool _timerCorrectionDone = false;
private int _normalInterval = 5000;
public Form1()
{
InitializeComponent();
//here you calculate the second that should elapsed
var now = new TimeSpan(0,DateTime.Now.Minute, DateTime.Now.Second);
int corrTo5MinutesUpper = (now.Minutes/5)*5;
if (now.Minutes%5>0)
{
corrTo5MinutesUpper = corrTo5MinutesUpper + 5;
}
var upperBound = new TimeSpan(0,corrTo5MinutesUpper, 60-now.Seconds);
var correcFirstStart = (upperBound - now);
timer1.Interval = (int)correcFirstStart.TotalMilliseconds;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
// just do a correction like this
if (!_timerCorrectionDone)
{
timer1.Interval = _normalInterval;
_timerCorrectionDone = true;
}
}

Related

Timer variable is null which is declared for countdown timer?

I have this code which is used for countdown in C#. I can't seem to find why my variable t is null. I tried this code on a separate project and it works well. I tried to incorporate it into another project and it says that variable t is null.
public partial class tracker : Form
{
System.Timers.Timer t;
int h1, m1, s1;
public tracker()
{
InitializeComponent();
}
private void tracker_Load(object sender, EventArgs e)
{
t = new System.Timers.Timer();
t.Interval = 1000; //1s
t.Elapsed += OnTimeEventWork;
}
private void btnLogin_Click(object sender, EventArgs e)
{
t.Start();
btnLogin.Enabled = false;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectedText = DateTime.Now.ToString("MM/dd/yyyy\n");
richTextBox2.SelectedText = "Time In\n";
richTextBox3.SelectedText = DateTime.Now.ToString("HH:mm:ss\n");
richTextBox4.SelectedText = "\n";
richTextBox5.SelectedText = "\n";
}
}
You are getting error t as null, because t.Start() is calling before instantiation of Timer object t.
To solve this issue, either instantiate before t.start() or create an object inside the constructor.
Like
public tracker()
{
InitializeComponent();
//Here you can instantiate Timer class
t = new System.Timers.Timer();
t.Interval = 1000; //1s
t.Elapsed += OnTimeEventWork;
}
private void tracker_Load(object sender, EventArgs e)
{
//Do NOT create object of Timer class here
}
private void btnLogin_Click(object sender, EventArgs e)
{
t.Start();
...
}

Best way to run a background task with timer

The following code run a task which check, each 5 seconds, the status of a database. I had to use the BeginInvoke but I'm not sure is the best way to do:
public btnDatabaseStatus()
{
InitializeComponent();
if (!DesignerProperties.GetIsInDesignMode(this))
Global.LM.SetTraduzioniWindow(this);
Init();
DispatcherOperation dbStatDispatcher = null;
try
{
dbStatDispatcher = App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
Timer timer = new Timer(5000);
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}));
}
catch (Exception ex)
{
if (dbStatDispatcher != null) dbStatDispatcher.Abort();
}
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
if (App.Current!=null) App.Current.Dispatcher.BeginInvoke(new Action(() => { IsDbConnected = Dbs[0].IsConnected; }));
}
private void Init()
{
Dbs = null;
Dbs = Global.DBM.DB.Values.Where(d => d.IsExternalDB).ToList();
lstvDatabase.ItemsSource = Dbs;
}
I'm afraid concerning the closing of main application as sometimes the Dispatcher is null. Any hints to improve the code?
Forget about Dispatcher.BeginInvoke and System.Threading.Timer.
Use a WPF DispatcherTimer:
public btnDatabaseStatus()
{
InitializeComponent();
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
timer.Tick += OnTimerTick;
timer.Start();
}
private void OnTimerTick(object sender, EventArgs e)
{
IsDbConnected = Dbs[0].IsConnected;
}
Or shorter:
public btnDatabaseStatus()
{
InitializeComponent();
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
timer.Tick += (s, e) => IsDbConnected = Dbs[0].IsConnected;
timer.Start();
}
If the Tick handler is supposed to do some long-running task, you may declare it async:
private async void OnTimerTick(object sender, EventArgs e)
{
await SomeLongRunningMethod();
// probably update UI after await
}

Countdown timer using System.Timers.Timer in WPF application [duplicate]

How can I implement the following in my piece of code written in WPF C#?
I have a ElementFlow control in which I have implemented a SelectionChanged event which (by definition) fires up a specific event when the control's item selection has changed.
What I would like it to do is:
Start a timer
If the timer reaches 2 seconds then launch a MessageBox saying ("Hi there") for example
If the selection changes before the timer reaches 2 seconds then the timer should be reset and started over again.
This is to ensure that the lengthy action only launches if the selection has not changed within 2 seconds but I am not familiar with the DispatcherTimer feature of WPF as i am more in the know when it comes to the normal Timer of Windows Forms.
Thanks,
S.
Try this:
private int timerTickCount = 0;
private bool hasSelectionChanged = false;
private DispatcherTimer timer;
In your constructor or relevant method:
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 1); // will 'tick' once every second
timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
And then an event handler:
private void Timer_Tick(object sender, EventArgs e)
{
DispatcherTimer timer = (DispatcherTimer)sender;
if (++timerTickCount == 2)
{
if (hasSelectionChanged) timer.Stop();
else MessageBox.Show("Hi there");
}
}
Finally, to make this work, you just need to set the hasSelectionChanged variable when the selection has changed according to your SelectionChanged event.
I've figured the complete code out as such:
DispatcherTimer _timer;
public MainWindow()
{
_myTimer = new DispatcherTimer();
_myTimer.Tick += MyTimerTick;
_myTimer.Interval = new TimeSpan(0,0,0,1);
}
private void ElementFlowSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_counter = 0;
_myTimer.Stop();
_myTimer.Interval = new TimeSpan(0, 0, 0, 1);
_myTimer.Start();
}
private int _counter;
public int Counter
{
get { return _counter; }
set
{
_counter = value;
OnPropertyChanged("Counter");
}
}
private void MyTimerTick(object sender, EventArgs e)
{
Counter++;
if (Counter == 2)
{
_myTimer.Stop();
MessageBox.Show(“Reached the 2 second countdown”);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler e = PropertyChanged;
if (e != null)
{
e(this, new PropertyChangedEventArgs(propertyName));
}
}
look here is the code of how to use DispatherTimer and you can add your own logic in it. that will depends on you..
private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, object e)
{
// show your message here..
}
To use a DispatcherTimer:
private DispatcherTimer _timer;
public void StartTimer()
{
if (_timer == null)
{
_timer = new DispatcherTimer();
_timer.Tick += _timer_Tick;
}
_timer.Interval = TimeSpan.FromSeconds(2);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
MessageBox.Show("Hi there");
_timer.Stop();
}
void SelectionChangedEvent()
{
StartTimer();
}

How to let user enter an integer and start timer based off on that value

I am in the process of creating my first c# project, a personal time tracking application. Pretty basic so far however before I get any further I would like to have the timer working properly.
So far the timer will start / stop and reset. However a curious thing that I wanted to be able to do was for the user to set a time and have the counter start from there.
So if they wanted to start at 20 minutes and have it count up, then it would
example: 00:20:00 would count from 20 and add to it.
However so far I have not figured it out.
Here is the code:
namespace TimeTracker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TimerBox.Text = string.Format("00:00:00");
}
int ss = 0;
public void StartButton_click(object sender, EventArgs e)
{
timer1.Start();
timer1.Enabled = true;
timer1.Interval = 1000;
}
public void StopButton_click(object sender, EventArgs e)
{
timer1.Stop();
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
public void ResetButton_click(object sender, EventArgs e)
{
ss = 0;
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
private void timer1_Tick(object sender, EventArgs e)
{
ss++;
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
}
}
Here is the application:
http://imgur.com/VNXVrtp
Any help would be appreciated, I can provide more details if you would like!
EDIT: Since it was unclear, my question is:
What process would be better for coding this, adding to the integer or if there is a better way of implementing this?
You can set the initial value of that ss variable to any predefined integer entered by user, e.g.
DateTime _dt = DateTime.Parse(TimertBox.Text);
int ss = _dt.Second + _dt.Minute * 60 + _dt.Hour * 3600;
Try something like...
public partial class Form1 : Form
{
private TimeSpan Offset = new TimeSpan();
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
public Form1()
{
InitializeComponent();
timer1.Interval = 1000;
UpdateTime();
}
public void StartButton_click(object sender, EventArgs e)
{
TimeSpan TS;
if (TimeSpan.TryParse(TimerBox.Text, out TS))
{
Offset = TS;
}
else
{
MessageBox.Show("Invalid Starting Time. Resetting to Zero");
Offset = new TimeSpan();
}
SW.Restart();
UpdateTime();
timer1.Start();
}
public void StopButton_click(object sender, EventArgs e)
{
SW.Stop();
timer1.Stop();
}
public void ResetButton_click(object sender, EventArgs e)
{
Offset = new TimeSpan();
if (SW.IsRunning)
{
SW.Restart();
}
else
{
SW.Reset();
}
UpdateTime();
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateTime();
}
private void UpdateTime()
{
TimerBox.Text = Offset.Add(SW.Elapsed).ToString(#"hh\:mm\:ss");
}
}
Try using the timer normally (from 00:00:00.00), and when updating your output label / textbox / etc. just add the time the user has written.

Event Handler Problem in Windows Service

I am going nuts. I can't figure out the problem.
I have a windows service that has a simple timer method. If I start the service, it always gives out exception at onTimerElapsed event. But If I write my XMLOperation methods in a different method(but not timer which I only need) and call it from program.cs, it works just fine. The working code is at the bottom also.
partial class DatabaseService : ServiceBase
{
Timer timer = new Timer();
public DatabaseService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer.Interval = 10000;
timer.Enabled = true;
timer.Elapsed += new ElapsedEventHandler(onElapsedTime);
timer.Start();
}
protected override void OnStop()
{
timer.Enabled = false;
}
public void onElapsedTime(object source, ElapsedEventArgs e)
{
try
{
XMLOperations operation = new XMLOperations();
operation.WebServiceFlexiCampaigns("http://www.flexi.com.tr/data/xml/pazaryeri/mobil.xml");
operation.WebServiceShopMilesCampaignsXMLRead("http://www.shopandmiles.com/xml/3_119_3.xml");
operation.WebServiceBonusCampaignsXMLRead("http://www.bonus.com.tr/apps/getcampaignxml.aspx?type=campaigns");
}
catch (Exception ex)
{
StreamWriter SW;
SW = File.CreateText("c:\\1.txt");
SW.WriteLine(ex.Message);
SW.Close();
}
}
here is the working one, but this time I could not manage to work that code in periods of time like I can do in timer event. I call test method manually from program.cs
partial class DatabaseService : ServiceBase
{
Timer timer = new Timer();
public DatabaseService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer.Interval = 10000;
timer.Enabled = true;
timer.Elapsed += new ElapsedEventHandler(onElapsedTime);
timer.Start();
}
protected override void OnStop()
{
timer.Enabled = false;
}
public void test()
{
try
{
XMLOperations operation = new XMLOperations();
operation.WebServiceFlexiCampaigns("http://www.flexi.com.tr/data/xml/pazaryeri/mobil.xml");
operation.WebServiceShopMilesCampaignsXMLRead("http://www.shopandmiles.com/xml/3_119_3.xml");
operation.WebServiceBonusCampaignsXMLRead("http://www.bonus.com.tr/apps/getcampaignxml.aspx?type=campaigns");
}
catch (Exception ex)
{
StreamWriter SW;
SW = File.CreateText("c:\\1111.txt");
SW.WriteLine(ex.Message);
SW.Close();
}
}
You can try this thread (see SamAgain response):
http://social.msdn.microsoft.com/Forums/en/clr/thread/8fbca78b-5078-4a12-8abb-4051076febbb
Hope it will work.

Categories

Resources