I created a function that gets number of milliseconds and then runs the progress bar but the result is that the progress bar run less time than defined.
this.timerProgress.Tick += new System.EventHandler(this.timerProgress_Tick);
public void AnimateProgBar(int milliSeconds)
{
if (!timerProgress.Enabled)
{
this.Invoke((MethodInvoker)delegate { pbStatus.Value = 0; });
timerProgress.Interval = milliSeconds / 100;
timerProgress.Enabled = true;
}
}
private void timerProgress_Tick(object sender, EventArgs e)
{
if (pbStatus.Value < 100)
{
pbStatus.Value += 1;
pbStatus.Refresh();
}
else
{
timerProgress.Enabled = false;
}
}
using AnimateProgBar(100), will end up creating a Interval of 1 millisecond.
timerProgress.Interval = milliSeconds; //do not divide by 100
this.timerProgress.Tick += new System.EventHandler(this.timerProgress_Tick);
public void AnimateProgBar(int milliSeconds)
{
if (!timerProgress.Enabled)
{
this.Invoke((MethodInvoker)delegate { pbStatus.Value = 0; });
timerProgress.Interval = milliSeconds; //do not divide by 100
timerProgress.Enabled = true;
}
}
private void timerProgress_Tick(object sender, EventArgs e)
{
if (pbStatus.Value < 100)
{
pbStatus.Value += 1;
pbStatus.Refresh();
}
else
{
timerProgress.Enabled = false;
}
}
A call to AnimateProgBar(1000) will result in the following calculation: 1000 / 100. That equals 10.
The Timer interval is already in milliseconds. So you're effectively setting the interval to 10ms.
Related
This is what I have so far, but it doesn't matter to what number I change the progressbar1.value is changed too, I still get the same result 0. I am guessing that the problem lies in the timespent Variable, but I can't figure it out.
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
int sum = 0;
for (int i = 1; i <= 100; i++)
{
// run the process here
Thread.Sleep(100);
// end process
sum = sum + i;
backgroundWorker1.ReportProgress(i);
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
// displays the sum of the process
e.Result = sum;
}
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label5.Text = e.ProgressPercentage.ToString() + "%";
DateTime starttime = DateTime.Now;
var timespent = DateTime.Now - starttime;
double secondsremaining = (double)(timespent.TotalSeconds / progressBar1.Value) * (progressBar1.Maximum - progressBar1.Value);
label7.Text = "Time remaining:" + (int)secondsremaining;
Console.WriteLine(secondsremaining);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
label5.Text = "Processing Cancelled";
}
else if (e.Error != null)
{
label5.Text = e.Error.Message;
}
else
{
label5.Text = "Sum = " + e.Result.ToString();
}
label6.Text = "";
}
private void button11_Click_1(object sender, EventArgs e)
{
//Checks if the background worker is busy running operations
if (!backgroundWorker1.IsBusy)
{
//this method will start the excution of the opreation
backgroundWorker1.RunWorkerAsync();
}
else
{
label6.Text = "The operation is being completed, please wait...";
}
}
}
}
}
The code you have is reasonably close, but you have a mistake: your starttime variable is a local variable, which you reset to the current time immediately before trying to use it to compute the elapsed time. Thus, the elapsed time is always zero, or very close to.
You should move the variable to be an instance field, so that it can persist between the progress updates:
DateTime starttime;
private void backgroundWorker1_DoWork(
object sender, System.ComponentModel.DoWorkEventArgs e)
{
int sum = 0;
// Using UtcNow will ensure the time calculation is correct even if
// the work occurs during a daylight saving time change-over
starttimme = DateTime.UtcNow;
for (int i = 1; i <= 100; i++)
{
// run the process here
Thread.Sleep(100);
// end process
sum = sum + i;
backgroundWorker1.ReportProgress(i);
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
// displays the sum of the process
e.Result = sum;
}
private void backgroundWorker1_ProgressChanged(
object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label5.Text = e.ProgressPercentage.ToString() + "%";
var timespent = DateTime.UtcNow - starttime;
// Casting to double here is superfluous. TotalSeconds is already a
// double, and its presence in the expression results in the rest of
// the values being promoted to double and the expression type being double.
double secondsremaining =
(double)(timespent.TotalSeconds / progressBar1.Value) *
(progressBar1.Maximum - progressBar1.Value);
label7.Text = "Time remaining:" + (int)secondsremaining;
Console.WriteLine(secondsremaining);
}
Try this one.
public static void Main(string[] args)
{
DateTime StartTime = DateTime.Now;
/// do something here... that actually takes time
Thread.Sleep(TimeSpan.FromSeconds(1));
/// next estimate update
{
double WorkDone = 0.10; // e.g. 10%... give some indication how much work has been done between 0 and 1
TimeSpan TimeSpent = DateTime.Now - StartTime;
TimeSpan TimeOverall = TimeSpan.FromTicks((long) (TimeSpent.Ticks / WorkDone));
TimeSpan TimeRemaining = TimeOverall - TimeSpent;
Console.WriteLine(TimeRemaining.TotalSeconds);
}
}
The DateTime.Now resolution is in Ticks or 1E-7 seconds, if you request the time too often then no time has passed. For higher resolution you need performance counters that can measure CPU cycles.
int millisecondi = 0;
public Form1()
{
InitializeComponent();
player.Top = screen.Height - player.Height;
player.BackgroundImage = Properties.Resources.stand;
if (mario)
{
label1.Text = "Mario";
}
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
progressBar1.Value = 100;
}
private void timer1_Tick(object sender, EventArgs e)
{
index++;
//replay gif
millisecondi++;
if (millisecondi == 1000)
{
progressBar1.Value = progressBar1.Value - 1;
if (progressBar1.Value <= 0)
{
MessageBox.Show("Sei Morto");
}
}
}
The problem is in the timer1_Tick.
It is enabled automatically and its interval is 1 millisecond.
Every second I want the progress bar to be "Progressbar value - 1" for example.
When it reaches 0 I want it to say "You died".
It enters in this cycle after 1 second, but it just doesn't work:
if (millisecondi == 1000)
{
progressBar1.Value = progressBar1.Value - 1;
if (progressBar1.Value <= 0)
{
MessageBox.Show("Sei Morto");
}
}
Timer ticks once and then it stops: To make it tick constantly, change the Tick event to:
private void timer1_Tick(object sender, EventArgs e)
{
index++;
millisecondi++;
timer1.Stop();
if (millisecondi == 1000)
{
progressBar1.Value = progressBar1.Value - 1;
if (progressBar1.Value <= 0)
{
MessageBox.Show("Sei Morto");
}
}
else
{
timer1.Start(); // will 'retick' if millisecondi != 1000
}
}
As you mentioned that code execution reaches to if (millisecondi == 1000) then there wouldn't be any problem with execution scenario so you should take care of other things like following:
Timer NameSpace : Make sure that your timer namespace is System.Windows.Forms.Timer
if It's ok that would work anyway your code looks correct to me, but if you still encounter this problem again try this code :
index++;
//replay gif
millisecondi++;
if (millisecondi == 1000)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke((MethodInvoker)
delegate
{
progressBar1.Value = progressBar1.Value - 1;
}
);
}
else
{
progressBar1.Value = progressBar1.Value - 1;
}
if (progressBar1.Value <= 0)
{
MessageBox.Show("Sei Morto");
}
}
I am using below code to display time left in hh:mm:ss format for example if duration is 30min, it will show like this 00:30:00 and after 1 min it will show 00:29:00, how can i also display the remaining seconds and decrease them accordingly.,
Edit
I tried timer1.Interval = 1000; and
examTime = examTime.Subtract(TimeSpan.FromSeconds(1));
But its not showing me seconds reducing each second, How do i do it ?
public SubjectExamStart()
{
InitializeComponent();
examTime = TimeSpan.FromMinutes(double.Parse(conf[1]));
label1.Text = examTime.ToString();
timer1.Interval = 60 * 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (sender == timer1)
{
if (examTime.TotalMinutes > 0)
{
examTime = examTime.Subtract(TimeSpan.FromMinutes(1));
label1.Text = examTime.ToString();
}
else
{
timer1.Stop();
MessageBox.Show("Exam Time is Finished");
}
}
}
Instead of Subtracting TimeSpan.FromMinutes you need to subtract from TimeSpan.FromSeconds
public SubjectExamStart()
{
InitializeComponent();
examTime = TimeSpan.FromSeconds(double.Parse(conf[1]));
label1.Text = examTime.ToString();
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (sender == timer1)
{
if (examTime.TotalMinutes > 0)
{
examTime = examTime.Subtract(TimeSpan.FromSeconds(1));
label1.Text = examTime.ToString();
}
else
{
timer1.Stop();
MessageBox.Show("Exam Time is Finished");
}
}
}
If you want to format the Time Span value while assigning to Label... You can use below..
label1.Text = examTime.ToString(#"dd\.hh\:mm\:ss");
To do this properly, you will need to keep a track of when the timer was started
DateTime examStartTime;
System.Windows.Forms.Timer runTimer;
TimeSpan totalExamTime = new TimeSpan(1, 30, 0); // Set exam time to 1 hour 30 minutes.
if (runTimer == null)
runTimer = new System.Windows.Forms.Timer();
runTimer.Interval = 200;
runTimer.Tick -= new EventHandler(runTimerTick);
runTimer.Tick += new EventHandler(runTimerTick);
examStartTime = DateTime.Now;
runTimer.Start();
Then in the event handler you can do:
public void runTimerTick(object sender, EventArgs e)
{
TimeSpan currentExamTime = DateTime.Now - examStartTime;
if (currentExamTime > totalExamTime)
{
MessageBox.Show("Exam Time is Finished");
runTimer.Stop();
runTimer.Tick -= new EventHandler(runTimerTick);
runTimer.Dispose();
}
}
I hope this helps.
try this hope this will work for u
set timer interval=1000
minremain=1200000; //Should be in milisecond
timerplurg.satrt();
private void timerplurg_Tick(object sender, EventArgs e)
{
minremain = minremain - 1000; //substring One second from total time
string Sec = string.Empty;
if (minremain <= 0)
{
lblpurgingTimer.Text = "";
timerplurg.Stop();
return;
}
else
{
var timeSpan = TimeSpan.FromMilliseconds(Convert.ToDouble(minremain));
var seconds = timeSpan.Seconds;
if (seconds.ToString().Length.Equals(1))
{
Sec = "0" + seconds.ToString();
}
else
{
Sec = seconds.ToString();
}
string Totaltime = "Remaing Second: " + Sec;
lblpurgingTimer.Text = Totaltime;
}
I would like to know how to create a label that adds sum + 1 every 5 seconds? I've tried with an if loop but unfortunately it resets one second later.
Thank you in advantage for your attention
using System.Diagnostics;
// using system.diagnotics voor stopwatch
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Stopwatch sw = new Stopwatch();
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
sw.Start();
if (timer1.Enabled == true) { button1.Text = "stop"; }
else { button1.Text = "false"; sw.Stop(); }
}
private void timer1_Tick(object sender, EventArgs e)
{
int hours = sw.Elapsed.Hours;
int minutes = sw.Elapsed.Minutes;
int seconds = sw.Elapsed.Seconds;
int sum = 0;
label1.Text = hours + ":" ;
if (minutes < 10) { label1.Text += "0" + minutes + ":"; }
else { label1.Text += minutes + ":"; }
if (seconds < 10) { label1.Text += "0" + seconds ; }
else { label1.Text += seconds ; }
if (seconds ==5) { sum = sum +=1; }
label2.Text = Convert.ToString(sum);
}
}
}
sum should be a class field. Also you can use custom format string for elapsed TimeSpan.
int sum = 0;
private void timer1_Tick(object sender, EventArgs e)
{
// int sum = 0; local variable will be set to zero on each timer tick
label1.Text = sw.Elapsed.ToString(#"hh\:mm\:ss");
// btw this will not update sum each five seconds
if (sw.Elapsed.Seconds == 5)
sum++; // same as sum = sum +=1;
label2.Text = sum.ToString();
}
Your current implementation will increase sum only if current elapsed timeout's second value is five. Which could never happen (depending on your timer interval). If you have timer interval set to 1000 milliseconds, then you can increase sum on each tick, but set label2.Text = (sum % 5).ToString().
every time your stopwatch TICKS, sum is inside TICK and it will reset and start from
int sum=0;
so try to make sum variable GLOBAL outside timer1_Tick event and it will continue increasing.
You will have to move sum out of the timer callback as you are setting it to 0 each time the timer elapses
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int sum = 0;
private DateTime lastUpdate;
private Stopwatch sw = new Stopwatch();
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = string.Format("{0:00}:{1:00}:{2:00}",
sw.Elapsed.Hours, sw.Elapsed.Minutes, sw.Elapsed.Seconds);
if (DateTime.Now >= lastUpdate.AddSeconds(5))
{
sum++;
lastUpdate = DateTime.Now;
label2.Text = sum.ToString();
}
}
private void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
sw.Stop();
button1.Text = "stop";
}
else
{
sum = 0;
lastUpdate = DateTime.Now;
timer1.Enabled = true;
sw.Start();
button1.Text = "Start";
}
}
I'm trying to make a timer tick for 80 minutes while the progress bar keeps track of the current time, but the progress bar in C# Forms will not be accurate to the timer ticks. I have it set up for the timer to tick once every 1000 ms and in that tick it will add a step to the progress bar. The progress bar will not act as it should with the timer, does anyone know how to fix this?
public Form1()
{
InitializeComponent();
initTimers();
}
public void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(1);
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "Go")
{
timer1.Start();
button1.Text = "Stop";
}
else
{
timer1.Stop();
button1.Text = "Go";
}
}
public void initTimers()
{
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000;
}
public void progressTimers()
{
progressBar1.Value = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 2;
progressBar1.Step = 1;
progressBar1.Visible = true;
}
You need to change this line:
progressBar1.Maximum = 2;
to:
progressBar1.Maximum = 80 * 60; // minutes * 60
And make sure you call progressTimers() :).