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);
}
Related
I have .Net framwork 4.7.2 application, which handles cpu-intensive workload.
It uses system.timers.timer, intend to force program timeout after x mins.
The timer sometimes is not able to trigger on time.
Any suggestion on making the timer work properly, without loosing workload efficiency?
Following is the code to demonstrate the issue.
The timer set to triggered every 5 secs, but result is not as expected, which is shown in screenshot.
Please note that size of taskCollection is not predictable.
class Program
{
static void Main(string[] args)
{
var taskCollection = new string[new Random().Next(10, 100)];
SetupTimer();
Parallel.ForEach(taskCollection
, new ParallelOptions { MaxDegreeOfParallelism = -1 }
, task =>
{
SlowTask();
}
);
}
static void SetupTimer()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += (s_, e_) =>
{
OnTimedEvent(s_, e_);
};
aTimer.Interval = 5000;
aTimer.Enabled = true;
Console.WriteLine($"Timer has been started at {DateTime.Now}.");
}
static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine($"Timer has been triggered at {DateTime.Now}.");
}
static void SlowTask()
{
long nthPrime = FindPrimeNumber(10000000); //set higher value for more time
}
static long FindPrimeNumber(int n)
{
int count = 0;
long a = 2;
while (count < n)
{
long b = 2;
int prime = 1;
while (b * b <= a)
{
if (a % b == 0)
{
prime = 0;
break;
}
b++;
}
if (prime > 0)
{
count++;
}
a++;
}
return (--a);
}
}
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'");
}
}
}
}
}
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));
}
}
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);
}
}
}