i have a windows service set to run at certain times, it runs first time but i cant seem to work out how to tell it to run the next day when it gets to end of times..
this is what i am trying...
protected override void OnStart(string[] args)
{
log.Info("Info - Service Start");
string timeToRunStr = "17:11";
var timeStrArray = timeToRunStr.Split(';');
foreach (var strTime in timeStrArray)
{
timeToRun.Add(TimeSpan.Parse(strTime));
}
ResetTimer();
}
void ResetTimer()
{
log.Info("Info - Reset Timer");
try
{
TimeSpan currentTime = DateTime.Now.TimeOfDay;
TimeSpan nextRunTime = timeToRun[0];
foreach (TimeSpan runTime in timeToRun)
{
if (currentTime < runTime)
{
nextRunTime = runTime;
// log.Info("Info - in loop");
break;
}
else {
TimeSpan test = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 16, 51, 0).Subtract(DateTime.Now);
nextRunTime = test;
}
}
_timer = new Timer((nextRunTime - currentTime).TotalSeconds * 1000);
log.Info("Info - Timer : " + (nextRunTime - currentTime).TotalSeconds * 1000);
log.Info("Info - nextRuntime : " + nextRunTime);
log.Info("Info - currentTime : " + currentTime);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
}
catch (Exception ex)
{
log.Error("This is my timer error - ", ex);
}
}
check out these alternatives: :
DateTime of next 3am occurrence
Control activities with a timer, see model:
class Program
{
static void my_task(Object obj)
{
Console.WriteLine("task being performed.");
}
static TimerCallback timerDelegate;
static Timer timer;
static void Main(string[] args)
{
DateTime now = DateTime.Now;
DateTime today = now.Date.AddHours(12);
DateTime next = now <= today ? today : today.AddDays(1);
timerDelegate = new TimerCallback(my_task);
// hence the first after the next
timer = new Timer(timerDelegate, null, next - DateTime.Now, TimeSpan.FromHours(24));
}
}
Related
I'm new to C#.
I'm trying to make a simple task reminder program.
The problem is, when I try to add a countdown for deadline time, it won't work correctly.
My first task countdown will be overwritten by my second task countdown, the same case when I add the third task and so on.
Here is the code of the correlating part.
private void buttonSave_Click(object sender, EventArgs e)
{
if (this.textBox_Task.Text != "")
{
listView1.View = View.Details;
ListViewItem lvwItem = listView1.Items.Add(dateTimePicker1.Text);
var day = dateTimePicker1.Value.Day;
var month = dateTimePicker1.Value.Month;
var year = dateTimePicker1.Value.Year;
endTime = new DateTime(year,month,day);
//Console.WriteLine(day);
//Console.WriteLine(month);
//Console.WriteLine(year);
//Console.WriteLine(dTime
Timer t = new Timer();
t.Interval = 500;
t.Tick += new EventHandler(t_Tick);
t.Start();
lvwItem.SubItems.Add(textBox_Task.Text);
lvwItem.SubItems.Add(textBox_Note.Text);
lvwItem.SubItems.Add("");
this.dateTimePicker1.Focus();
this.textBox_Note.Focus();
this.textBox_Task.Focus();
this.textBox_Task.Clear();
this.textBox_Note.Clear();
}
else
{
MessageBox.Show("Please enter a task to add.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.textBox_Task.Clear();
this.textBox_Note.Clear();
}
}
void t_Tick(object sender, EventArgs e)
{
TimeSpan ts = endTime.Subtract(DateTime.Now);
var hari = dateTimePicker1.Value.Day;
Console.WriteLine(ts.Days);
for (int i = 0; i < listView1.Items.Count; i++)
{
if (ts.Days == 0)
{
listView1.Items[i].SubItems[3].Text = "DEADLINE";
}
else
{
listView1.Items[i].SubItems[3].Text = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds to go'");
}
}
}
It would be much appreciated for anyone who willing to help.
Thanks in advance.
Here is the link to the picture of my problem
What you are doing now is on each button click override the current endTime object by a new one like:
endTime = new DateTime(year,month,day);
If you assign a new DateTime object to endTime. You override the old one. So the first button click will work but the second will create a new object of DateTime and assign it to endTime. Next you are calculating the time difference on that one object DateTime. So it is logic that it will be the same time for each listview items
If you want to have more than one DateTime use a List to store it in like
List<DateTime> _times = new List<DateTime>();
In the button click method add the DateTime to the list
// here add the datetime to the list
DateTime dateTime = new DateTime(year, month, day);
_times.Add(dateTime);
Next you can loop thru the dates and calculate for each one the time difference in the tick method:
foreach (var dateTime in _times)
{
TimeSpan ts = dateTime.Subtract(DateTime.Now);
// etc..
}
Also you are creating a timer for each time to calculate after 500 ms. You now can use one timer this is more efficient than crating one for each time. Just assign this in the constructor
public Form1()
{
InitializeComponent();
Timer t = new Timer();
t.Interval = 500;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
Whole code
public partial class Form1 : Form
{
// This is the list where the DateTimes are stored so you can have more values
List<DateTime> _times = new List<DateTime>();
public Form1()
{
InitializeComponent();
// Assign the timer here
Timer t = new Timer();
t.Interval = 500;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (this.textBox_Task.Text != "")
{
listView1.View = View.Details;
ListViewItem lvwItem = listView1.Items.Add(dateTimePicker1.Text);
var day = dateTimePicker1.Value.Day;
var month = dateTimePicker1.Value.Month;
var year = dateTimePicker1.Value.Year;
// Add Datetime to list
DateTime dateTime = new DateTime(year, month, day);
_times.Add(dateTime);
lvwItem.SubItems.Add(textBox_Task.Text);
lvwItem.SubItems.Add(textBox_Note.Text);
lvwItem.SubItems.Add("");
this.dateTimePicker1.Focus();
this.textBox_Note.Focus();
this.textBox_Task.Focus();
this.textBox_Task.Clear();
this.textBox_Note.Clear();
}
else
{
MessageBox.Show("Please enter a task to add.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.textBox_Task.Clear();
this.textBox_Note.Clear();
}
}
void t_Tick(object sender, EventArgs e)
{
// loop thru all datetimes and calculate the diffrence
foreach (var dateTime in _times)
{
// Call the specific date and subtract on it
TimeSpan ts = dateTime.Subtract(DateTime.Now);
var hari = dateTimePicker1.Value.Day;
Console.WriteLine(ts.Days);
for (int i = 0; i < listView1.Items.Count; i++)
{
if (ts.Days == 0)
{
listView1.Items[i].SubItems[3].Text = "DEADLINE";
}
else
{
listView1.Items[i].SubItems[3].Text = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds to go'");
}
}
}
}
}
How to create a function to auto close the programe at 06:00 am no matter does it finished its job or not?
static void Main(string[] args)
{
//How to create a function to check the time and kill the programe
foreach(var job in toDayjobs)
{
runJob();
}
}
This code snippet should work.
Don't forget to add using System.Threading;
static void Main(string[] args)
{
CloseAt(new TimeSpan(6, 0, 0)); //6 AM
//Your foreach code here
Console.WriteLine("Waiting");
Console.ReadLine();
}
public static void CloseAt(TimeSpan activationTime)
{
Thread stopThread = new Thread(delegate ()
{
TimeSpan day = new TimeSpan(24, 00, 00); // 24 hours in a day.
TimeSpan now = TimeSpan.Parse(DateTime.Now.ToString("HH:mm")); // The current time in 24 hour format
TimeSpan timeLeftUntilFirstRun = ((day - now) + activationTime);
if (timeLeftUntilFirstRun.TotalHours > 24)
timeLeftUntilFirstRun -= new TimeSpan(24, 0, 0);
Thread.Sleep((int)timeLeftUntilFirstRun.TotalMilliseconds);
Environment.Exit(0);
})
{ IsBackground = true };
stopThread.Start();
}
This is the code to do that assuming you want to shut down the app #6:00 PM
private static bool isCompleted = false;
static void Main(string[] args)
{
var hour = 16;
var date = DateTime.Now;
if (DateTime.Now.Hour > hour)
date = DateTime.Now.AddDays(1);
var day = date.Day;
var timeToShutdown = new DateTime(date.Year, date.Month, day, 18, 0, 0).Subtract(DateTime.Now);
var timer = new System.Timers.Timer();
timer.Elapsed += Timer_Elapsed;
timer.Interval = timeToShutdown.TotalMilliseconds;
timer.Start();
//Do the forloop here
isCompleted= true;
Console.WriteLine("Press any key to continue");
Console.Read();
}
private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var timer = (sender as System.Timers.Timer);
timer.Stop();
timer.Dispose();
if(isCompleted == false)
throw new Exception("Work was not completed");
Environment.Exit(0);
}
I am writing a WinForm application to use SNMP calls either every 30 seconds or 1 minute.
I have a timer working for calling my SNMP commands, but I want to add a texbox counter that display the total time elapsed during the operation.
There are many problems I am having so here is a list:
I want my SNMP timer 'timer' to execute once before waiting the allotted time so I have it going off at 3 seconds and then changing the interval in my handler. But this sometimes makes the timer go off multiple times which is not what I want.
Every time 'timer' goes off and my SNMP calls execute my counter timer 'appTimer' becomes out of sync. I tried a work around where I check if it is in the other handler and then just jump the timer to its appropriate time. Which works but I feel this is making it too complicated.
My last issue, that I know of, happens when I stop my application using my stop button which does not completely exit the app. When I go to start another run the time between both timers is becomes even greater and for some reason my counting timer 'appTimer' starts counting twice as fast.
I hope this description isn't too confusing but here is my code anyway:
using System;
using System.Net;
using SnmpSharpNet;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static bool stop = false;
static bool min = true, eye = false, firstTick = false;
static string ipAdd = "", fileSaveLocation = "";
static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
static System.Windows.Forms.Timer appTimer = new System.Windows.Forms.Timer();
static int alarmCounter = 1, hours = 0, minutes = 0, seconds = 0, tenthseconds = 0, count = 0;
static bool inSNMP = false;
static TextBox textbox, timeTextbox;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
textbox = outputBox;
timeTextbox = timeBox;
ipAdd = "192.168.98.107";
fileSaveLocation = "c:/Users/bshellnut/Desktop/Eye.txt";
min = true;
inSNMP = false;
}
private void IPtext_TextChanged(object sender, EventArgs e)
{
ipAdd = IPtext.Text;
}
private void stopButton_Click(object sender, EventArgs e)
{
stop = true;
timer.Stop();
appTimer.Stop();
count = 0;
hours = minutes = seconds = tenthseconds = 0;
inSNMP = false;
}
// This is the method to run when the timer is raised.
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
inSNMP = true;
timer.Stop();
if (firstTick == true)
{
// Sets the timer interval to 60 seconds or 1 second.
if (min == true)
{
timer.Interval = 1000 * 60;
}
else
{
timer.Interval = 1000 * 30;
}
}
// Displays a message box asking whether to continue running the timer.
if (stop == false)
{
textbox.Clear();
// Restarts the timer and increments the counter.
alarmCounter += 1;
timer.Enabled = true;
System.IO.StreamWriter file;
//if (eye == true)
//{
file = new System.IO.StreamWriter(fileSaveLocation, true);
/*}
else
{
file = new System.IO.StreamWriter(fileSaveLocation, true);
}*/
// SNMP community name
OctetString community = new OctetString("public");
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3)
param.Version = SnmpVersion.Ver2;
// Construct the agent address object
// IpAddress class is easy to use here because
// it will try to resolve constructor parameter if it doesn't
// parse to an IP address
IpAddress agent = new IpAddress(ipAdd);
// Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);
// Define Oid that is the root of the MIB
// tree you wish to retrieve
Oid rootOid;
if (eye == true)
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.14"); // ifDescr
}
else
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.15");
}
// This Oid represents last Oid returned by
// the SNMP agent
Oid lastOid = (Oid)rootOid.Clone();
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.GetBulk);
// In this example, set NonRepeaters value to 0
pdu.NonRepeaters = 0;
// MaxRepetitions tells the agent how many Oid/Value pairs to return
// in the response.
pdu.MaxRepetitions = 5;
// Loop through results
while (lastOid != null)
{
// When Pdu class is first constructed, RequestId is set to 0
// and during encoding id will be set to the random value
// for subsequent requests, id will be set to a value that
// needs to be incremented to have unique request ids for each
// packet
if (pdu.RequestId != 0)
{
pdu.RequestId += 1;
}
// Clear Oids from the Pdu class.
pdu.VbList.Clear();
// Initialize request PDU with the last retrieved Oid
pdu.VbList.Add(lastOid);
// Make SNMP request
SnmpV2Packet result;
try
{
result = (SnmpV2Packet)target.Request(pdu, param);
}
catch (SnmpSharpNet.SnmpException)
{
timer.Stop();
textbox.Text = "Could not connect to the IP Provided.";
break;
}
// You should catch exceptions in the Request if using in real application.
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
textbox.Text = "Error in SNMP reply. " + "Error " + result.Pdu.ErrorStatus + " index " + result.Pdu.ErrorIndex;
lastOid = null;
break;
}
else
{
// Walk through returned variable bindings
foreach (Vb v in result.Pdu.VbList)
{
// Check that retrieved Oid is "child" of the root OID
if (rootOid.IsRootOf(v.Oid))
{
count++;
textbox.Text += "#" + count + " " + v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
" " + v.Value.ToString() + Environment.NewLine;
file.WriteLine("#" + count + ", " + v.Oid.ToString() + ", " + SnmpConstants.GetTypeName(v.Value.Type) +
", " + v.Value.ToString(), true);
if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW)
lastOid = null;
else
lastOid = v.Oid;
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
else
{
//Console.WriteLine("No response received from SNMP agent.");
textbox.Text = "No response received from SNMP agent.";
//outputBox.Text = "No response received from SNMP agent.";
}
}
target.Close();
file.Close();
}
else
{
// Stops the timer.
//exitFlag = true;
count = 0;
}
}
private static void ApplicationTimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
tenthseconds += 1;
if (tenthseconds == 10)
{
seconds += 1;
tenthseconds = 0;
}
if (inSNMP && !firstTick)
{
if (min)
{
seconds = 60;
}
else
{
textbox.Text += "IN 30 SECONDS!!!";
if (seconds < 30)
{
seconds = 30;
}
else
{
seconds = 60;
}
}
}
if(seconds == 60)
{
seconds = 0;
minutes += 1;
}
if(minutes == 60)
{
minutes = 0;
hours += 1;
}
timeTextbox.Text = (hours < 10 ? "00" + hours.ToString() : hours.ToString()) + ":" +
(minutes < 10 ? "0" + minutes.ToString() : minutes.ToString()) + ":" +
(seconds < 10 ? "0" + seconds.ToString() : seconds.ToString()) + "." +
(tenthseconds < 10 ? "0" + tenthseconds.ToString() : tenthseconds.ToString());
inSNMP = false;
firstTick = false;
}
private void eyeButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = true;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void jitterButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = false;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void Seconds_CheckedChanged(object sender, EventArgs e)
{
min = false;
}
private void Minutes_CheckedChanged(object sender, EventArgs e)
{
min = true;
}
private void exitButton_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void savetextBox_TextChanged(object sender, EventArgs e)
{
fileSaveLocation = savetextBox.Text;
}
}
}
This is very easy to do with a single timer. The timer has a 1/10th second resolution (or so) and can be used directly to update the elapsed time. You can then use relative elapsed time within that timer to fire off your SNMP transaction, and you can reschedule the next one dynamically.
Here's a simple example
using System;
using System.Drawing;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
DateTime lastSnmpTime;
TimeSpan snmpTime = TimeSpan.FromSeconds(30);
DateTime startTime;
TextBox elapsedTimeTextBox;
Timer timer;
public Form1()
{
timer = new Timer { Enabled = false, Interval = 10 };
timer.Tick += new EventHandler(timer_Tick);
elapsedTimeTextBox = new TextBox { Location = new Point(10, 10), ReadOnly = true };
Controls.Add(elapsedTimeTextBox);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
startTime = DateTime.Now;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// Update elapsed time
elapsedTimeTextBox.Text = (DateTime.Now - startTime).ToString("g");
// Send SNMP
if (DateTime.Now - lastSnmpTime >= snmpTime)
{
lastSnmpTime = DateTime.Now;
// Do SNMP
// Adjust snmpTime as needed
}
}
}
Updated Q&A
With this code the timer fires once at the beginning where after I
press the stop button and call timer.Stop() and then press my start
button the timer doesn't fire until roughly 12 seconds later. Will
resetting the DateTimes fix this?
When the user presses the Start button, set lastSnmpTime = DateTime.MinValue. This causes the TimeSpan of (DateTime.Now - lastSnmpTime) to be over 2,000 years, so it will be greater than snmpTime and will fire immediately.
Also my output time in the text box looks like this: 0:00:02.620262.
Why is that? Is there a way to make it display only 0:00:02.62?
When you subtract two DateTime values, the result is a TimeSpan value. I used a standard TimeSpan formatting string of "g". You can use a custom TimeSpan formatting string of #"d\:hh\:mm\:ss\.ff" to get days:hours:minutes:seconds.fraction (2 decimal places).
Also will the timer go on and print out to the text box when it is run
for over 9 hours? Because I plan to have this running for 24 hrs+
If you use the custom format with 'd' to show the number of days, it will run for TimeSpan.MaxValue which is slightly more than 10,675,199 days, which is more than 29,000 years.
I Have This in C#
private void counter_Tick(object sender, EventArgs e)
{
Time.Text = String.Format("{0:000}", Hour) + ":" + String.Format("{0:00}", Minute) + ":" + String.Format("{0:00}", Second);
if (Second != 00)
{
Second = Second - 1;
}
else if (Minute != 00)
{
Minute = Minute - 1;
Second = 59;
}
else if (Hour != 00)
{
Hour = Hour - 1;
Minute = 59;
}
else
{
counter.Stop();
Time.ForeColor = Color.Red;
}
}
Which Does work but when it gets to minus an hour to add to minutes, it goes from 00 minutes to 58 minutes instead of 59
EG.
From: 001:00:00
To: 000:58:59
And is there a better way to make a countdown timer that does something when it hits 000:00:00???
Well let's see what happens when the time is 10:00:00.
Subtract one hour: 09:00:00.
Set minutes to 59: 09:59:00.
If you notice the time is off by one minute (10:00:00 - 09:59:00 = 00:01:00). The solution is to set the seconds to 59 also. So now our code is.
// ...
else if (Hour != 00)
{
Hour = Hour - 1;
Minute = 59;
Second = 59;
}
// ...
You can use standard .Net classes for subtracting time:
private TimeSpan timeSpan;
private TimeSpan oneSecond = new TimeSpan(0, 0, 1);
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Time.Text = timeSpan.ToString();
if (timeSpan == TimeSpan.Zero)
{
Time.ForeColor = Color.Red;
timer.Stop();
return;
}
timeSpan -= oneSecond;
}
Initialize timespan when you starting your timer (I used System.Timers.Timer):
timeSpan = new TimeSpan(1, 0, 0);
Timer timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
You also need to set Second to 59. Else, once the timer ticks again, it immediately switches to else if (Minute != 00) and decrements Minute (which is already 59) by one.
DateTime start;
DateTime final;
private void start()
{
start = DateTime.Now;
final = start + TimeSpan.FromHours(1);
}
private void counter_Tick(object sender, EventArgs e)
{
start = DateTime.Now;
Time.Text = (final-start).Hours.ToString() + ":" + (final-start).Minutes.ToString() + ":" + (final-start).Seconds.ToString();
if (final == start)
{
//final code
}
}
How do i reset the timer at the end of the day automatically and how do i display the time and date it was executed the last time?
The program is -
namespace Time_Writer
{
class Program
{
static int count = 1;
static double seconds;
static int total = 10000;
private static System.Timers.Timer aTimer;
static void Main(string[] args)
{
ReadCountFromFile();
aTimer = new System.Timers.Timer();
aTimer.Elapsed +=new System.Timers.ElapsedEventHandler(aTimer_Elapsed);
aTimer.Interval = 5000;
aTimer.Enabled = true;
Console.WriteLine("Press Enter To Exit The Program\n");
Console.ReadLine();
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
}
private static void ReadCountFromFile()
{
try
{
if (File.Exists(".\\mynumber.dat"))
{
using (var file = File.Open(".\\mynumber.dat", FileMode.Open))
{
byte[] bytes = new byte[4];
file.Read(bytes, 0, 4);
count = BitConverter.ToInt32(bytes, 0);
total = total - count;
Console.WriteLine("Total count left is = {0}", total);
Console.WriteLine("Limit = 10000");
Console.WriteLine("Count = {0}", count);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Problem reading file.");
}
}
static void CurrentDomain_ProcessExit(Object sender, EventArgs e)
{
using (var file = File.Open(".\\mynumber.dat", FileMode.OpenOrCreate))
{
var buffer = BitConverter.GetBytes(count);
file.Write(buffer, 0, buffer.Length);
}
}
private static void aTimer_Elapsed(object source, ElapsedEventArgs e)
{
Console.WriteLine("Name is Yap {0}", e.SignalTime);
seconds += 5;
count += 1;
if (count>10000 || seconds == 86400)
{
aTimer.Enabled = false;
Console.WriteLine("\n\nTimer is off at {0}\n\n", e.SignalTime.TimeOfDay.ToString());
}
}
}
}
I modify your code and wrap your timer into a thread. I reduces the timer and count as well to make it easier to test. I'm sure there is a much better way to code it but this solution seems to work. you may need to adjust the thread sleep according to your need.
You can adjust when the process should stop and restart by playing with the condition
if (count > TOTAL || _processStart.AddSeconds(1) < DateTime.Now) )
in the function aTimer_Elapsed.
Currenlty the process restart if it has been running for more than 1s or the count is reach.
class Program
{
private static DateTime _processStart;
static int count = 1;
const int TOTAL = 15;
private static Timer aTimer;
private static Thread _process;
static void Main(string[] args)
{
_process = new Thread(DoProcess);
_process.Start();
Console.WriteLine("Press Enter To Exit The Program\n");
Console.ReadLine();
ProcessExit();
}
static void DoProcess()
{
_processStart = DateTime.Now;
ReadCountFromFile();
if (count < TOTAL)
{
Console.WriteLine("******START TIMER******");
aTimer = new Timer();
aTimer.Elapsed += aTimer_Elapsed;
aTimer.Interval = 500;
aTimer.Enabled = true;
while (aTimer.Enabled)
{
Thread.Sleep(1000);
}
Console.WriteLine("******END TIMER******");
ProcessExit();
DoProcess();
}
}
private static void ReadCountFromFile()
{
try
{
if (File.Exists(".\\mynumber.dat"))
{
using (var file = File.Open(".\\mynumber.dat", FileMode.Open))
{
byte[] bytes = new byte[4];
file.Read(bytes, 0, 4);
count = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("Total count left is = {0} / Limit = {1} / Count = {2}", TOTAL - count, TOTAL, count);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Problem reading file.");
}
}
static void ProcessExit()
{
using (var file = File.Open(".\\mynumber.dat", FileMode.OpenOrCreate))
{
var buffer = BitConverter.GetBytes(count);
file.Write(buffer, 0, buffer.Length);
}
}
private static void aTimer_Elapsed(object source, ElapsedEventArgs e)
{
//Console.WriteLine("Name is Yap {0}", e.SignalTime);
if (count < TOTAL)
{
count += 1;
Console.WriteLine("Count is {0}", count);
}
if (count > TOTAL || _processStart.AddSeconds(1) < DateTime.Now)
{
aTimer.Enabled = false;
Console.WriteLine("Timer is off at {0} count is {1}", e.SignalTime.TimeOfDay.ToString(),count);
}
}
}