so, i want this: if specific time passed (for example 9 hours) from loading form, than i want to show messagebox said "9 hours passed". my code is this:
public partial class Form1 : Form
{
Stopwatch stopWatch = new Stopwatch();
public Form1()
{
InitializeComponent();
stopWatch.Start();
}
private void button1_Click(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
}
and the problem is that i don't know where to write this part of code:
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
so, where i write this code? if you have better way of doing this, please show me.
In addition to using a Timer as outlined by the others, you can directly use the TotalHours() property of the TimeSpan returned by Stopwatch.Elapsed:
TimeSpan ts = stopWatch.Elapsed;
if (ts.TotalHours >= 9)
{
MessageBox.Show("passed: " + ts.TotalHours.ToString("0.00"));
}
What people are not appreciating is that it is very unlikely that the double hours will be exactly 9.00! Why not just ask your timer to fire once, after the time you want, 9 hours.
Timer timer;
public Form1()
{
InitializeComponent();
timer.Tick += timer_Tick;
timer.Interval = TimeSpan.FromHours(9).TotalMilliseconds;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
MessageBox.Show("9 hours passed");
}
In order to do a specific task after a specific period of time System.Forms.Timer should be used (in case of windows forms). You can use its Elapsed event and in that you can implement your conditions.
Try using Timer instead. Example from here
Timer timer;
public Form1()
{
InitializeComponent();
timer.Tick += new EventHandler(timer_Tick); // when timer ticks, timer_Tick will be called
timer.Interval = (1000) * (10); // Timer will tick every 10 seconds
timer.Enabled = true; // Enable the timer
timer.Start(); // Start the timer
}
void timer_Tick(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
Use Timer:
Timer regularly invokes code. Every several seconds or minutes, it
executes a method. This is useful for monitoring the health of an
important program, as with diagnostics. The System.Timers namespace
proves useful.
see this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
stopWatch.Start();
tm.Interval = 1000;
tm.Enabled = true;
tm.Tick += new EventHandler(tm_Tick);
tm.Start();
}
void tm_Tick(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
}
Related
i'm trying to implement a simple countdown using Timer (using https://www.geoffstratton.com/cnet-countdown-timer code). it does work if i run the timer once but if i stop the timer or the timer goes to 00:00 the next time i'll start it, it will go 2x faster. if i stop it and start it again it will go 3x faster.
(my explaination may be not clear, i did a gif that demonstrate the problem)
https://media.giphy.com/media/fQr7sX6LNRECvQpCYP/giphy.gif
i'm very novice at c#, i usually figure things out but i cant get what's happening here.
I included the timer code. if somebody can help me with this it would be awesome!
Thanks !!!
private void btnStartTimer_Click(object sender, EventArgs e)
{
if (txtTimer.Text == "00:00")
{
MessageBox.Show("Please enter the time to start!", "Enter the Time", MessageBoxButtons.OK);
}
else
{
string[] totalSeconds = txtTimer.Text.Split(':');
int minutes = Convert.ToInt32(totalSeconds[0]);
int seconds = Convert.ToInt32(totalSeconds[1]);
timeLeft = (minutes * 60) + seconds;
btnStartTimer.Enabled = false;
btnCleartimer.Enabled = false;
txtTimer.ReadOnly = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
}
private void btnStopTimer_Click(object sender, EventArgs e)
{
timer1.Stop();
timeLeft = 0;
btnStartTimer.Enabled = true;
btnCleartimer.Enabled = true;
txtTimer.ReadOnly = false;
}
private void btnCleartimer_Click(object sender, EventArgs e)
{
txtTimer.Text = "00:00";
}
private void timer1_Tick(object sender, EventArgs e)
{
if (timeLeft > 0)
{
timeLeft = timeLeft - 1;
// Display time remaining as mm:ss
var timespan = TimeSpan.FromSeconds(timeLeft);
txtTimer.Text = timespan.ToString(#"mm\:ss");
// Alternate method
//int secondsLeft = timeLeft % 60;
//int minutesLeft = timeLeft / 60;
}
else
{
timer1.Stop();
SystemSounds.Exclamation.Play();
MessageBox.Show("Time's up!", "Time has elapsed", MessageBoxButtons.OK);
}
}
You need to unsubscribe from the event in your btnStopTimer_Click method:
timer1.Tick -= timer1_Tick;
You are adding the event to Count every time you start the timer. As a result, the first time you call it there is only one event, the second time two events and so on. As a result, you first go down one second, then two,....
I would recommend creating the timer separately and just call Start and Stop.
Alternativ, user Dmitry Korolev answered a good Approach if you don't want to create the timer somewhere else
timer1.Tick -= timer1_Tick;
Quick question. I'm doing a project that when I open the the form it starts a timer.
When the timer is 1:00 after 1 minute it goes to 0:59 like it's supposed to happen.
But when I put the timer to 2:00 after 1 minute it goes to 1:59. I put the timer interval faster just to see what it would look like. And when it reachs 1:00 instead of becoming 0:59 becomes 1:59. I know that my code is wrong but I can't correct it.
public partial class Form9 : Form
{
private int quick = 1800;
public Form9()
{
InitializeComponent();
}
private void Form9_Load(object sender, EventArgs e)
{
timer1 = new System.Windows.Forms.Timer();
timer1.Interval = 60000;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
quick--;
label1.Text = quick / 900 + ":" + ((quick % 60) >= 10 ? (quick % 60).ToString() : "0" + (quick % 60));
}
}
Thanks in advance!
You can use built-in type TimeSpan instead.
private TimeSpan quick = TimeSpan.FromHours(2); // 2 hours
private void timer1_Tick(object sender, EventArgs e)
{
quick -= TimeSpan.FromMinutes(1); // subtract 1 minute
label1.Text = string.Format("{0:h\\:mm}", quick);
}
How to format Timespan
I want to execute a method every hour on the hour. I wrote some code,but it is not enough for my aim. Below code is working every 60 minutes.
public void Start()
{
System.Threading.Timer timerTemaUserBilgileri = new System.Threading.Timer(new System.Threading.TimerCallback(RunTakip), null, tmrTemaUserBilgileri, 0);
}
public void RunTakip(object temauserID)
{
try
{
string objID = "6143566557387";
EssentialMethod(objID);
TimeSpan span = DateTime.Now.Subtract(lastRunTime);
if (span.Minutes > 60)
{
tmrTemaUserBilgileri = 1 * 1000;
timerTemaUserBilgileri.Change(tmrTemaUserBilgileri, 0);
}
else
{
tmrTemaUserBilgileri = (60 - span.Minutes) * 60 * 1000;
timerTemaUserBilgileri.Change(tmrTemaUserBilgileri, 0);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
}
catch (Exception ex)
{
timerTemaUserBilgileri.Change(30 * 60 * 1000, 0);
Utils.LogYaz(ex.Message.ToString());
}
}
public void EssentialMethod(objec obj)
{
//some code
lastRunTime = DateTime.Now;
//send lastruntime to sql
}
If you want your code to be executed every 60 minutes:
aTimer = new System.Timers.Timer(60 * 60 * 1000); //one hour in milliseconds
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//Do the stuff you want to be done every hour;
}
if you want your code to be executed every hour (i.e. 1:00, 2:00, 3:00) you can create a timer with some small interval (let's say a second, depends on precision you need) and inside that timer event check if an hour has passed
aTimer = new System.Timers.Timer(1000); //One second, (use less to add precision, use more to consume less processor time
int lastHour = DateTime.Now.Hour;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
if(lastHour < DateTime.Now.Hour || (lastHour == 23 && DateTime.Now.Hour == 0))
{
lastHour = DateTime.Now.Hour;
YourImportantMethod(); // Call The method with your important staff..
}
}
I agree with SeƱor Salt that the chron job should be the first choice. However, the OP asked for every hour on the hour from c#. To do that, I set up the first timed event to fire on the hour:
int MilliSecondsLeftTilTheHour()
{
int interval;
int minutesRemaining = 59 - DateTime.Now.Minute;
int secondsRemaining = 59 - DateTime.Now.Second;
interval = ((minutesRemaining * 60) + secondsRemaining) * 1000;
// If we happen to be exactly on the hour...
if (interval == 0)
{
interval = 60 * 60 * 1000;
}
return interval;
}
Timer timer = new Timer();
timer.Tick += timer_Tick;
timer.Enabled = true;
timer.Interval = MilliSecondsLeftTilTheHour();
The problem now is that if the above timer.Interval happens to be 45 minutes and 32 seconds, then the timer will continue firing every 45:32 not just the first time. So, inside the timer_Tick method, you have to readjust the timer.Interval to one hour.
void timer_Tick(object sender, EventArgs e)
{
// The Interval could be hard wired here to 60 * 60 * 1000 but on clock
// resets and if the job ever goes longer than an hour, why not
// recalculate once an hour to get back on track.
timer.Interval = MilliSecondsLeftTilTheHour();
DoYourThing();
}
Just a small comment based on /Anarion's solution that I couldn't fit into a comment.
you can create a timer with some small interval (let's say a second, depends on precision you need)
You don't need it to go with any precision at all, you're thinking "how do I check this hour is the hour I want to fire". You could alternatively think "How do I check the next hour is the hour I want to fire" - once you think like that you realise you don't need any precision at all, just tick once an hour, and set a thread for the next hour. If you tick once an hour you know you'll be at some point before the next hour.
Dim dueTime As New DateTime(Date.Today.Year, Date.Today.Month, Date.Today.Day, DateTime.Now.Hour + 1, 0, 0)
Dim timeRemaining As TimeSpan = dueTime.Subtract(DateTime.Now)
t = New System.Threading.Timer(New System.Threading.TimerCallback(AddressOf Method), Nothing, CType(timeRemaining.TotalMilliseconds, Integer), System.Threading.Timeout.Infinite)
How about something simpler? Use a one-minute timer to check the hour:
public partial class Form1 : Form
{
int hour;
public Form1()
{
InitializeComponent();
if(RunOnStartUp)
hour = -1;
else
hour = DateTime.Now.Hour;
}
private void timer1_Tick(object sender, EventArgs e)
{
// once per minute:
if(DateTime.Now.Hour != hour)
{
hour = DateTime.Now.Hour;
DailyTask();
}
}
private DailyTask()
{
// do something
}
}
Use a Cron Job on the server to call a function at the specified interval
Heres a link
http://www.thesitewizard.com/general/set-cron-job.shtml
What about trying the below code, the loop is determined to save your resources, and it is running every EXACT hour, i.e. with both minutes and seconds (and almost milliseconds equal to zero:
using System;
using System.Threading.Tasks;
namespace COREserver{
public static partial class COREtasks{ // partial to be able to split the same class in multiple files
public static async void RunHourlyTasks(params Action[] tasks)
{
DateTime runHour = DateTime.Now.AddHours(1.0);
TimeSpan ts = new TimeSpan(runHour.Hour, 0, 0);
runHour = runHour.Date + ts;
Console.WriteLine("next run will be at: {0} and current hour is: {1}", runHour, DateTime.Now);
while (true)
{
TimeSpan duration = runHour.Subtract(DateTime.Now);
if(duration.TotalMilliseconds <= 0.0)
{
Parallel.Invoke(tasks);
Console.WriteLine("It is the run time as shown before to be: {0} confirmed with system time, that is: {1}", runHour, DateTime.Now);
runHour = DateTime.Now.AddHours(1.0);
Console.WriteLine("next run will be at: {0} and current hour is: {1}", runHour, DateTime.Now);
continue;
}
int delay = (int)(duration.TotalMilliseconds / 2);
await Task.Delay(30000); // 30 seconds
}
}
}
}
Why is everyone trying to handle this problem with a timer?
you're doing two things... waiting until the top of the hour and then running your timer every hour on the hour.
I have a windows service where I needed this same solution. I did my code in a very verbose way so that it is easy to follow for anyone. I know there are many shortcuts that can be implemented, but I leave that up to you.
private readonly Timer _timer;
/// starts timer
internal void Start()
{
int waitTime = calculateSleepTime();
System.Threading.Thread.Sleep(waitTime);
object t = new object();
EventArgs e = new EventArgs();
CheckEvents(t, e);
_timer.Start();
}
/// runs business logic everytime timer goes off
internal void CheckEvents(object sender, EventArgs e)
{
// do your logic here
}
/// Calculates how long to wait until the top of the hour
private int calculateSleepTime()
{
DateTime now = DateTime.Now;
int minutes = now.Minute * 60 * 1000;
int seconds = now.Second * 1000;
int substrahend = now.Millisecond + seconds + minutes;
int minuend = 60 * 60 * 1000;
return minuend - substrahend;
}
Here's a simple, stable (self-synchronizing) solution:
while(true) {
DoStuff();
var now = DateTime.UtcNow;
var previousTrigger = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0, now.Kind);
var nextTrigger = previousTrigger + TimeSpan.FromHours(1);
Thread.Sleep(nextTrigger - now);
}
Note that iterations may be skipped if DoStuff() takes longer than an hour to execute.
How to stop a timer after some numbers of ticks or after, let's say, 3-4 seconds?
So I start a timer and I want after 10 ticks or after 2-3 seconds to stop automatically.
Thanks!
You can keep a counter like
int counter = 0;
then in every tick you increment it. After your limit you can stop timer then. Do this in your tick event
counter++;
if(counter ==10) //or whatever your limit is
yourtimer.Stop();
When the timer's specified interval is reached (after 3 seconds), timer1_Tick() event handler will be called and you could stop the timer within the event handler.
Timer timer1 = new Timer();
timer1.Interval = 3000;
timer1.Enabled = true;
timer1.Tick += new System.EventHandler(timer1_Tick);
void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop(); // or timer1.Enabled = false;
}
i generally talking because you didn't mention which timer, but they all have ticks... so:
you'll need a counter in the class like
int count;
which you'll initialize in the start of your timer, and you'll need a dateTime like
DateTime start;
which you'll initialize in the start of your timer:
start = DateTime.Now;
and in your tick method you'll do:
if(count++ == 10 || (DateTime.Now - start).TotalSeconds > 2)
timer.stop()
here is a full example
public partial class meClass : Form
{
private System.Windows.Forms.Timer t;
private int count;
private DateTime start;
public meClass()
{
t = new Timer();
t.Interval = 50;
t.Tick += new EventHandler(t_Tick);
count = 0;
start = DateTime.Now;
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
if (count++ >= 10 || (DateTime.Now - start).TotalSeconds > 10)
{
t.Stop();
}
// do your stuff
}
}
Assuming you are using the System.Windows.Forms.Tick. You can keep track of a counter, and the time it lives like so. Its a nice way to use the Tag property of a timer.
This makes it reusable for other timers and keeps your code generic, instead of using a globally defined int counter for each timer.
this code is quiet generic as you can assign this event handler to manage the time it lives, and another event handler to handle the specific actions the timer was created for.
System.Windows.Forms.Timer ExampleTimer = new System.Windows.Forms.Timer();
ExampleTimer.Tag = new CustomTimerStruct
{
Counter = 0,
StartDateTime = DateTime.Now,
MaximumSecondsToLive = 10,
MaximumTicksToLive = 4
};
//Note the order of assigning the handlers. As this is the order they are executed.
ExampleTimer.Tick += Generic_Tick;
ExampleTimer.Tick += Work_Tick;
ExampleTimer.Interval = 1;
ExampleTimer.Start();
public struct CustomTimerStruct
{
public uint Counter;
public DateTime StartDateTime;
public uint MaximumSecondsToLive;
public uint MaximumTicksToLive;
}
void Generic_Tick(object sender, EventArgs e)
{
System.Windows.Forms.Timer thisTimer = sender as System.Windows.Forms.Timer;
CustomTimerStruct TimerInfo = (CustomTimerStruct)thisTimer.Tag;
TimerInfo.Counter++;
//Stop the timer based on its number of ticks
if (TimerInfo.Counter > TimerInfo.MaximumTicksToLive) thisTimer.Stop();
//Stops the timer based on the time its alive
if (DateTime.Now.Subtract(TimerInfo.StartDateTime).TotalSeconds > TimerInfo.MaximumSecondsToLive) thisTimer.Stop();
}
void Work_Tick(object sender, EventArgs e)
{
//Do work specifically for this timer
}
When initializing your timer set a tag value to 0 (zero).
tmrAutoStop.Tag = 0;
Then, with every tick add one...
tmrAutoStop.Tag = int.Parse(tmrAutoStop.Tag.ToString()) + 1;
and check if it reached your desired number:
if (int.Parse(tmrAutoStop.Tag.ToString()) >= 10)
{
//do timer cleanup
}
Use this same technique to alternate the timer associated event:
if (int.Parse(tmrAutoStop.Tag.ToString()) % 2 == 0)
{
//do something...
}
else
{
//do something else...
}
To check elapsed time (in seconds):
int m = int.Parse(tmrAutoStop.Tag.ToString()) * (1000 / tmrAutoStop.Interval);
DateTime newDate = new DateTime(2013, 1, 1);
void AddTime()
{
timer1.Interval = 600000;
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(+3);
lblDate.Text = newDate.ToString();
}
For some reason changing the timer1.Interval does not change the speed of 3 months being added to the newDate, it is always constant. I am trying to have 1 minute real life time equal 3 months in the game.
I am using C#.
Your initial timer interval is bit larger. Below is sample complete application. working as expected
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DateTime newDate = new DateTime(2013, 1, 1);
public Form1()
{
InitializeComponent();
AddTime(); // call the method, otherwise timer will not start
}
void AddTime()
{
timer1.Interval = 60000; // every minute (1 minute = 60000 milliseconds)
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(3);
label1.Text = newDate.ToString();
}
// if you need to set timet interval after timer start, do as below
private void button1_Click(object sender, EventArgs e)
{
timer1.Stop();
timer1.Interval = 30000; // set interval 30 seconds
timer1.Start();
}
}
}
Make sure the value .Interval is the one you want.
You have 600 000 that is 600 seconds or 10 min.
Did you give enough time to run the event?
Debug it and put a breakpoing.
Your interval is way too high currently, it's 600 seconds instead of 60:
DateTime newDate = new DateTime(2013, 1, 1);
void AddTime()
{
timer1.Interval = 60000; // was 600 seconds, now 60
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(3); // + sign shouldn't be here
lblDate.Text = newDate.ToString();
}
Edit:
Now I see that you aren't calling AddTime() at the moment, and are unclear of where to do it. It is hard to say without more information, but if you are using Winforms you could use the form's load event. Or if it's a class you could use the constructor to call it.
Basically the method that initialises the object that you are working with.
You're going about it the wrong way. First compute the RATIO of "game time" to "normal time". Months, however, are problematic since the number of days in a month is variable. Instead, we can use a quarter (365 / 4) and work from there. Use a Stopwatch to track how much time has elapsed, and add that to the reference date to get "real time". "Game time", then, is simply the elapsed time multiplied by the ratio, and then added to the reference time. Using this model, the Timer Interval() is IRREVELANT; we could update once a minute, once a second, or four times a second, and the code for determining real/game time is completely the same...and all times remain accurate when we update the display:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// update once per second, but the rate here is IRREVELANT...
// ...and can be changed without affecting the real/game timing
timer1.Interval = 1000;
timer1.Tick += new EventHandler(timer1_Tick);
}
private DateTime dtReal;
private DateTime dtGame;
private DateTime dtReference;
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
private double TimeRatio = (TimeSpan.FromDays(365).TotalMilliseconds / 4.0) / TimeSpan.FromMinutes(1).TotalMilliseconds;
private void button1_Click(object sender, EventArgs e)
{
StartTime();
}
private void StartTime()
{
dtReference = new DateTime(2013, 1, 1);
SW.Restart();
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
UpdateTimes();
DisplayTimes();
}
private void UpdateTimes()
{
double elapsed = (double)SW.ElapsedMilliseconds;
dtReal = dtReference.AddMilliseconds(elapsed);
dtGame = dtReference.AddMilliseconds(elapsed * TimeRatio);
}
private void DisplayTimes()
{
lblReference.Text = dtReference.ToString();
lblReal.Text = dtReal.ToString();
lblGame.Text = dtGame.ToString();
}
}
Edit: Added screenshots...
Just after ONE minute = approx 3 months
Just after FOUR minutes = approx 1 year