Reputation: 185
I'm trying to increment my ProgressBar with a timer.
Timer interval is 2 minutes, so the progressbar should be at 100 when 2 minutes are over.
Timer Tick-Event:
private void timer1_Tick(object sender, EventArgs e)
{
if (toolStripProgressBar1.Value < 100)
{
toolStripProgressBar1.Value++;
}
string serviceName = textBox1.Text;
string ipAddress = currentIp.ToString();
string type = "ovh";
string virtualMachineName = "s";
Dictionary<string, object> payload = new Dictionary<string, object>();
payload.Add("ipAddress", ipAddress);
payload.Add("type", type);
payload.Add("virtualMachineName", virtualMachineName);
try
{
client.PostAsync(
String.Format("/dedicated/server/{0}/virtualMac", serviceName),
payload
).Wait();
Log(String.Format("Using IP {0} ", ipAddress), 2);
ipList.Remove(currentIp);
}
catch (Exception ex)
{
if(ex.InnerException.ToString().Contains("A Virtual Mac already exists"))
{
Log("Mac already exists for this IP, continuing.", 1);
ipList.Remove(currentIp);
Log(String.Format("Removed IP {0} ", currentIp), 2);
timer1_Tick(null, EventArgs.Empty);
}
}
// Reset progressbar, if progressbar is full
if (toolStripProgressBar1.Value == 100)
{
toolStripProgressBar1.Value = 0;
}
}
Somehow the progressbar does not change at all.
It works somehow when I set the interval from my timer to 600 though.
Upvotes: 1
Views: 747
Reputation: 39152
Here is how I would approach it. Make your Timer fire only once per second. This is how often the ProgressBar will be updated, and also how often we check if two minutes has passed, indicating we should start the payload again. Record the current time when you start the timer. Every time the Tick() event fires, subtract the start time from the current time to get a TimeSpan
. You can use this to determine if two minutes has passed or not.
Might look something like:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private DateTime startTime;
private TimeSpan twoMinutes = TimeSpan.FromMinutes(2);
private void Form1_Load(object sender, EventArgs e)
{
progressBar1.Maximum = 100;
timer1.Enabled = false;
timer1.Interval = 1000; // check only once per second
}
private void button1_Click(object sender, EventArgs e)
{
if (!timer1.Enabled)
{
progressBar1.Value = 0;
startTime = DateTime.Now;
Task.Run(() => {
PayloadCode();
});
timer1.Start();
MessageBox.Show("Timer Started.");
}
else
{
timer1.Stop();
MessageBox.Show("Timer Stopped.");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan ts = DateTime.Now.Subtract(startTime);
if (ts >= twoMinutes)
{
Task.Run(() => {
PayloadCode();
});
startTime = DateTime.Now;
progressBar1.Value = 0;
}
else
{
progressBar1.Value = (int)(ts.TotalMilliseconds / twoMinutes.TotalMilliseconds * 100);
}
}
private void PayloadCode()
{
// This is running in another thread!
// Invoke() if you need to update the GUI from here
// ... payload code ...
}
}
Upvotes: 0
Reputation: 52290
It's a mistake to tie the event timer interval to the value shown in the progress bar. The event timer interval should depend only on how often you want to refresh the display; the value shown in the progress bar depends on how much progress has actually passed.
For example, if you want a progress bar that reaches 100% after two minutes, you might do something like this:
To store progress:
DateTime _startTime;
To start the timer:
_startTime = DateTime.Now;
timer1.Start();
To handle the update:
timer1_Tick(object sender, EventArgs e)
{
//How long have we been running?
var secondsElapsed = (DateTime.Now - _startTime).TotalSeconds;
//How close are we to running for two minutes?
var percentComplete = (int)((float)secondsElapsed / 120F * 100F);
if (percentComplete > 100) percentComplete = 100;
//Set the progress bar
progressBar.Value = percentComplete;
//Do other stuff
}
This way, the progress bar will be accurate and won't depend on the timer interval.
Upvotes: 0
Reputation: 87
If I understand correctly, you want the progress bar to be full in 2 minutes, so you set the interval of your timer at that value in miliseconds (that is 120000)
But the interval is the interval between ticks, so every 2 minutes, your progress bar will increase by 1. That means your progress bar will be full in 200 minutes, or 3 hours and 20 minutes.
If you want it to work the way you described it, just set the interval to 1200, so that in 2 minutes the progress bar will be full.
EDIT: I now saw that you tried it with interval 600. Yes, that works, every 600 miliseconds you increment the progress bar value, so it will be full in 100 ticks, after 60000 miliseconds (one minute).
Also, you don't need the first "if" statement. You start at 0, keep incrementing it, and at one point it will be 99. You increment again, and in the same call of the Tick method you check if it reached 100, and reset it. So you always increment, no need for checking :)
ANOTHER EDIT: To understand what I explained, this is what I meant:
private void timer1_Tick(object sender, EventArgs e)
{
toolStripProgressBar1.Value++;
// Reset progressbar, if progressbar is full
if (toolStripProgressBar1.Value == 100)
{
toolStripProgressBar1.Value = 0;
// Do what needs to be done every 2 minutes
string serviceName = textBox1.Text;
string ipAddress = currentIp.ToString();
string type = "ovh";
string virtualMachineName = "s";
Dictionary<string, object> payload = new Dictionary<string, object>();
payload.Add("ipAddress", ipAddress);
payload.Add("type", type);
payload.Add("virtualMachineName", virtualMachineName);
try
{
client.PostAsync(
String.Format("/dedicated/server/{0}/virtualMac", serviceName),
payload
).Wait();
Log(String.Format("Using IP {0} ", ipAddress), 2);
ipList.Remove(currentIp);
}
catch (Exception ex)
{
if(ex.InnerException.ToString().Contains("A Virtual Mac already exists"))
{
Log("Mac already exists for this IP, continuing.", 1);
ipList.Remove(currentIp);
Log(String.Format("Removed IP {0} ", currentIp), 2);
timer1_Tick(null, EventArgs.Empty);
}
}
}
}
Upvotes: 2