Getting time until next event - c#

I have a sync timer in my app that fires up a function at a given time... now I want to know how much time is left until the next call to that function.
This is my call to the timer:
var syncTime = time.activitylog;
double time = TimeSpan.Parse(syncTime).TotalMilliseconds;
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = time;
myTimer.Start();
How do I get the time until next call?
Thanks

You can use another timer, and set the Interval of that the value that you want,exactly a part time of the Interval of original timer.
Then start them Simultaneously,I mean at the same time.
UPDATE :
Maybe this code describes my solution better :
public Form1()
{
InitializeComponent();
}
System.Windows.Forms.Timer trOriginal = new System.Windows.Forms.Timer();
System.Windows.Forms.Timer trRemain = new System.Windows.Forms.Timer();
double remain = 0;
private void button1_Click(object sender, EventArgs e)
{
trOriginal.Interval = 1000;
trRemain.Interval = 1;
trOriginal.Tick += new EventHandler(trOriginal_Tick);
trRemain.Tick += new EventHandler(trRemain_Tick);
trOriginal.Start();
trRemain.Start();
}
void trRemain_Tick(object sender, EventArgs e)
{
remain -= trRemain.Interval;
Console.WriteLine("remain MS to next event : " + remain);
}
void trOriginal_Tick(object sender, EventArgs e)
{
remain = trOriginal.Interval;
}

You can use a System.Diagnostics.Stopwatch to keep track of how much time has passed already and restart the Stopwatch with every tick of your Timer.
Stopwatch watch = new Stopwatch();
private void DisplayTimeEvent(object sender, EventArgs e)
{
watch.Restart();
// Whatever is supposed to happen, when the timer ticks
}
Now whenever you want to know how much time is left until the event is fired next, you can do this:
long timeLeft = myTimer.Interval - watch.ElapsedMilliseconds;

Related

WPF - A more accurate Timer

I'm new to CS and WPF. I'm going to get a DateTime object and set it as the beginning of my timer. But I used DispatcherTimer.Tick. I can feel it inaccurate with a little care and playing with window controls. It apparently its in a single thread beside other functions of program.
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
void timer_Tick(object sender, EventArgs e)
{
dateTime = dateTime.AddSeconds(1);
TimeTb.Text = dateTime.ToLongTimeString();
}
Is there another method to use for a more accurate timer?
Do not add up seconds. This is accurate:
private TimeSpan offset;
void timer_Tick(object sender, EventArgs e)
{
TimeTb.Text = (DateTime.Now - offset).ToLongTimeString();
}
If you want to show the time elapsed since a start time:
private DateTime start = DateTime.Now;
void timer_Tick(object sender, EventArgs e)
{
TimeTb.Text = (DateTime.Now - start).ToString();
}
Definitely. Take a look at the System.Diagnostics.Stopwatch class. You're re-inventing the wheel!

C# timer I can speed up but not slow down

I have a timer event setup and I would like to change how often the timer event happens by reading a number from a text box. If the box is '10' and you click the update button the event would trigger every 10ms then if you changed to '100' and clicked it would happen every 100ms and so on.
When I run the program however, i can speed up the event frequency (e.g. 100ms to 10ms) but I cannot slow it down (e.g. 10ms to 100ms). Here is the piece of my code that changes the timer when I click:
private void TimerButton_Click(object sender, EventArgs e)
{
getTime = ImgTimeInterval.Text;
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Enabled = false;
timer.Interval = timerMS;
timer.Elapsed += new ElapsedEventHandler(timerEvent);
timer.AutoReset = true;
timer.Enabled = true;
}
}
public void timerEvent(object source, System.Timers.ElapsedEventArgs e)
{
label1.Text = counter.ToString();
counter = (counter + 1) % 100;
}
If anyone knows what I may be doing wrong it would be greatly appreciated.
The problem with this code is, that you create a new Timer each time you click the button. Try to create the timer outside the method. You think it's only goes faster, but instead multiple timers trigger the timerEvent
private System.Timers.Timer _timer;
private void CreateTimer()
{
_timer = new System.Timers.Timer();
_timer.Enabled = false;
_timer.Interval = 100; // default
_timer.Elapsed += new ElapsedEventHandler(timerEvent);
_timer.AutoReset = true;
_timer.Enabled = true;
}
private void TimerButton_Click(object sender, EventArgs e)
{
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
_timer.Interval = timerMS;
}
}
public void timerEvent(object source, System.Timers.ElapsedEventArgs e)
{
label1.Text = counter.ToString();
counter = (counter + 1) % 100;
}
Make sure that the CreateTimer is called in the constructor/formload. Also you can now stop the timer within another button event. With _timer.Enabled = false;
You're always creating a new timer and never stopping the old timer. When you "change" it from 100 to 10 your 100ms timer is still firing every 100 ms, so every 100ms two timers are firing at around the same time.
You need to "remember" the old timer so that you can stop it. Or, better yet, just have only one timer that you change the interval on.
private System.Timers.Timer timer = new System.Timers.Timer();
public Form1()
{
timer.Enabled = false;
timer.AutoReset = true;
timer.Elapsed += timerEvent;
}
private void TimerButton_Click(object sender, EventArgs e)
{
getTime = ImgTimeInterval.Text;
bool isNumeric = int.TryParse(ImgTimeInterval.Text, out timerMS); //if number place number in timerMS
label2.Text = isNumeric.ToString();
if (isNumeric)
{
timer.Interval = timerMS;
timer.Enabled = true;
}
}
Well the basic problem is that you're building a new one every time. Make a private timer:
private System.Timers.Timer _timer = new System.Timers.Timer();
and then fix it up when the button is clicked:
if (isNumeric)
{
_timer.Stop();
_timer.Interval = timerMS;
_timer.Start();
}
and then in the .ctor, do this:
_timer.Elapsed += new ElapsedEventHandler(timerEvent);
Now you have a single timer that you are just modifying as the user changes the value in the text box.

Why does the interval of Windows.Forms.Timer decrease with the increased ticks?

I wrote a simple program that uses a timer to fade out a label. I found that the timer is so imprecise and the interval is shorter and shorter.
The following code proves my thought:
(I also implement it by StopWatch. The interval between ticks is almost equal.)
private void timer1_Tick(object sender, EventArgs e)
{
elapsed += timer1.Interval;
timerTest.AppendText(DateTime.UtcNow.Second.ToString() + "." + DateTime.UtcNow.Millisecond.ToString() + "\r\n");
if (elapsed >= target)
timer1.Stop();
}
int elapsed = 0;
int target = 4000;
private void button_Click(object sender, EventArgs e)
{
labelFadeout.ForeColor = Color.Greed;
elapsed = 0;
timer1.Interval = 100;
timer1.Tick += timer1_Tick;
timer1.Start();
}
And the 1st and 5th output result in a large difference!
[1st] [5th]
20.318 42.955
20.377 42.956
20.491 42.957
20.595 42.958
20.707 42.959
20.814 43.68
20.929 43.69
21.34 43.7
21.142 43.71
21.257 43.72
21.365 43.173
21.471 43.176
21.584 43.177
21.692 43.179
21.8 43.18
21.909 43.286
22.19 43.288
22.127 43.289
22.242 43.291
22.347 43.293
22.454 43.397
22.569 43.4
22.673 43.402
22.784 43.404
22.892 43.406
23.4 43.649
23.112 43.652
23.221 43.655
23.331 43.657
23.494 43.66
23.549 43.746
23.662 43.749
23.779 43.751
23.879 43.754
23.991 43.756
24.95 43.846
24.209 43.848
24.316 43.851
24.427 43.853
24.534 43.855
I've checked
Comparing the Timer Classes in the .NET Framework Class Library
and Limitations of the Windows Forms Timer Component's Interval Property
and still curious about how it could be so imprecise. Anyone could explain this??
Your method for testing your interval is off. You're really just getting a part of the current time at an interval and expecting it to be comparable to the last time you took it.
If you want to test how much time a timer really takes to tick at a 100 interval. Use an actual Stopwatch, and check out it's Elapsed to find out how much time as passed.
Stopwatch stopwatch = new Stopwatch();
int elapsed = 0;
int target = 4000;
private void timer1_Tick(object sender, EventArgs e)
{
elapsed += timer1.Interval;
timerTest.AppendText(stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Restart();
if (elapsed >= target)
timer1.Stop();
}
private void button1_Click(object sender, EventArgs e)
{
elapsed = 0;
timer1.Interval = 100;
timer1.Tick += timer1_Tick;
stopwatch.Start();
timer1.Start();
}
My result:
0.1055445
0.0872668
0.1121169
0.1032453
0.1066107
0.1097218
0.103818
0.1079014
...

Timer C# use in game development

I have a game in C# and I need to allow tournament mode in which each round will be of 2 minutes. How can I display the time from 0:00 up till 2:00 on the form?
I have this in a constructor:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
And this is the Event Handler
void Timer_Tick(object sender, EventArgs e)
{
this.textBox1.Text = DateTime.Now.ToLongTimeString();
}
but I don't know how I can begin the time from 0:00 instread of the current time.. I tried creating a DateTime instance but when I do myDateTime.ToString(); in the event handler, it just remains 0:00.
I tried searching but I can't find anything related.
Thanks a lot !
Save current time to field when you are starting timer:
_startTime = DateTime.Now;
timer.Start();
And calculate difference later:
void Timer_Tick(object sender, EventArgs e)
{
this.textBox1.Text = (DateTime.Now - _startTime).ToString(#"mm\:ss");
}
You need a member variable that is in scope for both the timer initialization and the Timer_Tick event handler.
class Something
{
DateTime _myDateTime;
Timer _timer;
public Something()
{
_timer = new Timer();
_timer.Interval = 1000;
_timer.Tick += Timer_Tick;
_myDateTime = DateTime.Now;
_timer.Start();
}
void Timer_Tick(object sender, EventArgs e)
{
var diff = DateTime.Now.Subtract(_myDateTime);
this.textBox1.Text = diff.ToString();
}
}
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
void Timer_Tick(object sender, EventArgs e)
{
label1.Text = stopWatch.ElapsedTicks.ToString();
}
You can store a DateTime.Now when you start the timer and then in every timer tick handler calculate how much time has passed between DateTime.Now and the stored start date. If you have a pause, you will need to also keep track of how long the game has been paused.
Considering the inconviniences with the above method, I would suggest you declare a StopWatch somewhere, instantiate and start it where you call timer.Start and then in your timer tick just read the Elapsed property of the StopWatch. You can even Stop and Start (pause) it if you need.

moving a button using a timer

I have four buttons that are called "ship1,ship2" etc.
I want them to move to the right side of the form (at the same speed and starting at the same time), and every time I click in one "ship", all the ships should stop.
I know that I need to use a timer (I have the code written that uses threading, but it gives me troubles when stopping the ships.) I don't know how to use timers.
I tried to read the timer info in MDSN but I didn't understand it.
So u can help me?
HERES the code using threading.
I don't want to use it. I need to use a TIMER! (I posted it here because it doesnt give me to post without any code
private bool flag = false;
Thread thr;
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
flag = false;
thr = new Thread(Go);
thr.Start();
}
private delegate void moveBd(Button btn);
void moveButton(Button btn)
{
int x = btn.Location.X;
int y = btn.Location.Y;
btn.Location = new Point(x + 1, y);
}
private void Go()
{
while (((ship1.Location.X + ship1.Size.Width) < this.Size.Width)&&(flag==false))
{
Invoke(new moveBd(moveButton), ship1);
Thread.Sleep(10);
}
MessageBox.Show("U LOOSE");
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
}
Have you googled Windows.Forms.Timer?
You can start a timer via:
Timer timer = new Timer();
timer.Interval = 1000; //one second
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
You'll need an event handler to handle the Elapsed event which is where you'll put the code to handle moving the 'Button':
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveButton();
}

Categories

Resources