How to count down time until timer's next tick? - c#

I have 2 timers. One of them is counting each time it ticks; while using steady interval, or one randomly generated. Second timer counts down to next tick in first timer.
As of right now I am doing as such:
private void btnStart_Click(object sender, EventArgs e)
{
nextClick = int.Parse(nudClickInterval.Value.ToString());
if (nudPlusMinus.Value != 0) tmrClickInterval.Interval = random.Next( int.Parse(nudClickInterval.Value.ToString()) - int.Parse(nudPlusMinus.Value.ToString()), int.Parse(nudClickInterval.Value.ToString()) + int.Parse(nudPlusMinus.Value.ToString()));
else tmrClickInterval.Interval = int.Parse(nudClickInterval.Value.ToString());
tmrClickInterval.Start();
}
private void tmrClickInterval_Tick(object sender, EventArgs e)
{
if (nudPlusMinus.Value == 0) tmrClickInterval.Interval = int.Parse(nudClickInterval.Value.ToString());
else tmrClickInterval.Interval = random.Next(int.Parse(nudClickInterval.Value.ToString()) - int.Parse(nudPlusMinus.Value.ToString()), int.Parse(nudClickInterval.Value.ToString()) + int.Parse(nudPlusMinus.Value.ToString()));
tmrNextClick.Interval = tmrClickInterval.Interval / 10;
tmrNextClick.Start();
content++;
nextClick = tmrClickInterval.Interval;
label1.Text = content.ToString();
}
private void tmrNextClick_Tick(object sender, EventArgs e)
{
if (nextClick <= 0) tmrNextClick.Stop();
else
{
nextClick = nextClick - (tmrClickInterval.Interval / 10);
lblNextClickCount.Text = (nextClick / 100).ToString();
}
}
I am setting up an interval of my count down timer by using first timer's interval dividing by 10. The problem is that I keep getting some errors such as: Value '0' is not a valid value for Interval. Interval must be greater than 0. at line: tmrNextClick.Interval = tmrClickInterval.Interval / 10;.
I'm not sure how to avoid my errors so I figure there might be a better way of counting down time until next timer tick. Plus, I'd want a count down in nice steady interval instead but I am getting quite confused and not sure how to manage this problem.
Hope for some help.

System.Windows.Forms.Timer has an int intervall. Dividing a number which is samller than 10 by 10 results in 0 (integer division!).
Try to use System.Timers.Timer, it has an interval of type double, or check for 0 and assign 1 in that case.

Related

C# Image rotation using timer

I am beginner C# user using WFA.Below is my code to get images to rotate every 4 ticks. please could I have some assistance to what I might have done incorrect.
private void timer1_Tick(object sender, EventArgs e)
{
int time = 0;
int pic = 0;
{
if (time >= 4)
pic++;
this.picBox1.Image = ImageList.Images[pic];
pic++;
if (time == 4 || time == 8 || time == 12 || time == 16)
this.lblCompany.Visible = true;
this.lsbHistory.ValueMember = ("User Clicks on at ___+ DateTime.Now.ToshortDateString");
every time your tick event gets called you set time to 0, that means it is lower then 4. you should take both time and pic values out of the event and reset time to 0 after.
I'd reccomend reading this https://msdn.microsoft.com/en-us/library/5557y8b4.aspx
on how to use breakpoints to have a beter look at what's happening in your code
private int time = 0;
private int pic = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if (time >= 4)
{
pic++;
time = 0;
this.picBox1.Image = ImageList.Images[pic];
//other logic you might have

Why when changing the comboBox item it's not changing the time counting in the correct way?

comboBox selectedindexchanged event:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
updateTime = Convert.ToInt32(comboBox1.SelectedItem);
xpProgressBar1.Position = 0;
counter = 0;
panel1.Select();
}
Update method:
public void Update()
{
counter += 1;
int position = (int)Math.Round((counter / updateTime) * 100);
xpProgressBar1.Text = counter.ToString() + " %";
xpProgressBar1.Position = position;
if (counter == 10)
{
if (!backgroundWorker1.IsBusy)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync();
}
counter = 0;
}
}
Timer tick event:
private void timer1_Tick(object sender, EventArgs e)
{
Update();
}
In the combBox by default it's on the first item the number 10 then i can change and select the item with the number 30,50,60,120,300 and all this values are in seconds.
The timer1 interval is set to 1000
The problem is when it's on 10 by default when running the program or if i change it back to 10 in the comboBox it's working good. What it does it's counting 10 seconds and updating the progressBar(xpProgressBar1) by 10's i mean each second the progressBar move by 10 percentages. So after 10 seconds it's getting to 100 percentages.
But when i change the comboBox to the second item to 30 it should count now 30 seconds untill 100%
So i'm not sure in what steps it should move and how to do it. Same if i change it to 120 then it should move progress 120 seconds and again i'm not sure what steps and how to do it so it will get to 100%
What it does now for example if i change it to 120 i see it start counting to 120 by steps of 1 but then when it's getting to 10% it's jumping back to the start and not continue.
It should keep counting the whole 120 seconds untill 100%
If i change it to 30 i see it also counting by steps of 1 each time but again in 10% it's jumping to the start and not continue.
When it's on 10 it's counting by steps of 10 untill 100% so i wonder what should i do and how in the others if it's on 120 to step by 120 ? not logic. So tmake them all to step by 1 also the when it's on 10 ? And again how to do it so it will not stop a 10% and start over again.
Now i changed in the Update method the line if (counter == 10) to:
if (counter == updateTime)
So now if i change in the comboBox select 120 it will count in steps of 1 untill 120 but now when it will get the progressBar to 100% it will keep counting untill 120.
There is no sync between the 120 seconds and the 100% of the progressBar.
EDIT
The Update method:
private int _updateCounter;
public void Update()
{
counter += 1;
xpProgressBar1.Text = counter.ToString() + " %";
xpProgressBar1.Position = _updateCounter++ * 10;
if (counter == 10)
{
if (!backgroundWorker1.IsBusy)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync();
}
counter = 0;
}
}
This is called prescaler (frequency divider). You have single clock source (Timer) with fastest frequency using which you can achieve needed frequencies by skipping certain calls (events).
All you miss is that skipping:
private int _timer1Ticks;
private void timer1_Tick(object sender, EventArgs e)
{
if(_timer1Ticks++ >= int.Parse(comboBox1.Text) / 10)
{
_timer1Ticks = 0;
Update();
}
}
This way Update will be called exactly 10 times, disregard of combobox selection.
And to calculate progress:
private int _updateCounter;
public void Update()
{
xpProgressBar1.Position = _updateCounter++ * 10;
...
// do not forget to stop timer
if(_updateCounter == 10)
{
timer1.Stop();
_updateCounter = 0; // add some cleanup if using timer more than once
_timer1Ticks = 0;
...
}
}

C# How to run delayed method in between timer ticks

I am using a timer to run a method every 16 minutes. I also want to run a second method every minute for 15 minutes in-between.
Below is the code I am using:
int count = 0;
private void cmdGo_Click(object sender, EventArgs e)
{
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 960000; // specify interval time - 16 mins
t.Tick += new EventHandler(timer_Tick);
t.Start();
}
void timer_Tick(object sender, EventArgs e)
{
RunMethod1();
while(count < 15)
{
//waiting for 60 seconds
DateTime wait = DateTime.Now;
do
{
Application.DoEvents();
} while (wait.AddSeconds(60) > DateTime.Now);
RunMethod2();
}
}
The above code seems to work fine but the ‘do while’ loop to wait for 60 seconds is very CPU heavy.
I tried to use Thread.Sleep(60000) but this freezes up the Interface and also tried to add a second timer within timer_Tick but this doesn’t seem possible. Can a second timer be added within the EventHandler of the first?
Is there any other method to achieve this without being so CPU intensive?
Thanks!
Warren
NOTE: Sorry guys, there was a typo in my original post. The 60 second wait do, while loop should have been within the while < 15 loop. Just updated the code snippet.
So:
RunMethod1() should be executed every 16 mins
RunMethod2() should be executed every 1 min (15 times) in between the 16 min tick
It would make more sense to have a counter to store how many times the clock has gone off. Then set your timer interval to fire once a minute so not doing anything in between...
That way you could just do...
private int Counter;
private void cmdGo_Click(object sender, EventArgs e)
{
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 60000; // specify interval time - 1 minute
t.Tick += new EventHandler(timer_Tick);
t.Start();
}
// Every 1 min this timer fires...
void timer_Tick(object sender, EventArgs e)
{
// If it has been 16 minutes then run RunMethod1
if (++Counter >= 16)
{
Counter = 0;
RunMethod1();
return;
}
// Not yet been 16 minutes so just run RunMethod2
RunMethod2();
}
You could await a task Delay so the UI will keep responding
async void timer_Tick(object sender, EventArgs e)
{
RunMethod1();
while (count < 15)
{
//waiting for 60 seconds
await Task.Delay(60000);
RunMethod2();
}
}

Is there other way to set long Timer Interval

I am making a program which has to check a data base once on every 30 or 60 minutes and display the results, if there are any, in the windows form interface. Of course, the other functions which the from provides access to, should still be usable while the data base check is being executed. To this end, I am using System.Timers.Timer which executes a method on a different thread from the UI one (If there is something wrong with using this approach, please feel free to comment on it). I wrote a small and simple program in order to test hot things work, only to notice that I cant really set the Interval to over ~ 1 minute ( I need 30 minutes to an hour). I came up with this solution:
public partial class Form1 : Form
{
int s = 2;
int counter = 1; //minutes counter
System.Timers.Timer t;
public Form1()
{
InitializeComponent();
t = new System.Timers.Timer();
t.Elapsed += timerElapsed;
t.Interval = 60000;
t.Start();
listBox1.Items.Add(DateTime.Now.ToString());
}
//doing stuff on a worker thread
public void timerElapsed(object sender, EventArgs e)
{
//check of 30 minutes have passed
if (counter < 30)
{
//increment counter and leave method
counter++;
return;
}
else
{
//do the stuff
s++;
string result = s + " " + DateTime.Now.ToString() + Thread.CurrentThread.ManagedThreadId.ToString();
//pass the result to the form`s listbox
Action action = () => listBox2.Items.Add(result);
this.Invoke(action);
//reset minutes counter
counter = 0;
}
}
//do other stuff to check if threadid`s are different
//and if the threads work simultaneously
private void button1_Click(object sender, EventArgs e)
{
for (int v = 0; v <= 100; v++)
{
string name = v + " " + Thread.CurrentThread.ManagedThreadId.ToString() +
" " + DateTime.Now.ToString(); ;
listBox1.Items.Add(name);
Thread.Sleep(1000); //so the whole operation should take around 100 seconds
}
}
}
But this way, the Elapsed event is being raised and the timerElapsed method called once every minute, it seems kinda useless. Is there a way to actually set longer timer interval ?
Interval is in miliseconds,so it seems that you've set your interval for 60 seconds:
t.Interval = 60000; // 60 * 1000 (1 minute)
If you want to have 1 hour interval then you need to change your interval to:
t.Interval = 3600000; // 60 * 60 * 1000 (1 hour)

GameTime and real time

I am trying to fill a rectangle in 3 seconds of real time
I want the increment to be a constant value to look nice and not have acceleration
and I am having trouble understanding what to do
this is my code
// constant
// 1.0f = 100% of rectangle, 3 sec = 3000.0 miliseconds
float addValue = 1.0f/3000.0f;
public override void Update(GameTime gameTime)
{
newGameTime += gameTime.ElapsedGameTime.Milliseconds;
// once the percentage is set to 0 this starts
if ((percentage < 1))
{
// calculate value here in order to time
percentage += addValue;
}
}
I've been trying all kind of crazy math to get it right but i completely lost it. :(
I know I should be using gameTime or newGameTime but I'm lost
I assume thats your update / rendering function.
Let's say, for example, that since the last rendering, 300ms elapsed. That means you'd have to add 100%/3000ms * 300ms = 10% to your rectangle.
-> You're missing the elapsed time in the calculation:
percentage += addValue * gameTime.ElapsedGameTime.Milliseconds;
I may be completely wrong with this answer according to what ccKep just mentioned in his comment.
But just in case it's what you're looking for, I put this together.
The main idea is having a timer event controling the increment. Even if the code I'm submitting isn't appropriate, maybe the idea will apply.
public int percentage;
public int Percentage
{
get { return percentage; }
set
{
percentage = value;
if (Percentage >= 0 && Percentage < 100)
{
progressBar1.Value = value;
}
else
{
Percentage = 0;
timer1.Stop();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Percentage = 0;
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
double addValue = 100 / 3;
Percentage += (int)addValue;
}

Categories