I've got a problem while programming a little game for myself.
I'm using the "System.Timers"-Timer and want to decrease the value of a progress bar
by every tick of the timer. There I faced my problem. I can't set a custom event handler to decrease the value of the progress bar.
I've using for the Timer the following code:
private Timer t = new Timer();
t.Interval = 600000;
t.Elapsed += Ended; //For ending event
t.AutoReset = true;
So how can I register a tick to decrease the value of the progress bar.
Thank you for your answers in advance.
Greetings
SirCodiac
You cant invoke a control from system.timers. In order to invoke the progress bar either use System.Windows.Forms.Timer or use a MethodInvoker as below:
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value++; }));
}
else
{
progressBar1.Value++;
}
}
Related
and on my c# program whenever i try:
System.Threading.Thread.Sleep(#);
as in delay number
It works, but whenever its "delaying" (i guess that's what its called) I can't get my form to pop up on my screen from the task bar, almost like reopening it (?). Could somebody help me make a thread that doesn't "freeze" the form? Thanks!
So, yeah, I have already tried
System.Threading.Thread.Sleep(#);
But that just freezes the form :/ thank you
oh btw, this is c#
You can use a Timer to delay a operation.
Example:
Timer timer = new Timer(10000);
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Start();
After 10000 MS the following Method will be called:
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//DoSomething
}
Sounds like you're after a background worker. This will allow you to keep your main form up but do some time consuming processing on another thread. Since you didn't post any specific code for your issue, I'm pasting in a snippet from a larger example found on MSDN
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
I want to show timer on UI such that when aplication star executing timer starts with 00:00:00 and when it completed its execution timer stops. Timer should show timing per second while running.
You can use the System.Windows.Forms.Timer, which is created for scenarios like yours. You can read more about in MSDN.
You should use the following code snippet as sample:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new System.EventHandler(timer_Tick);
timer.Start();
private void timer_Tick(object sender, System.EventArgs e)
{
this.Text = string.Format("{0:hh:MM:ss}", DateTime.Now);
}
Notice that you should dispose the Timer when you do not needed.
I am trying to repeat a code execution after predefined time passes and i don't want to mess up things by using threads. Is the below code a good practice?
Stopwatch sw = new Stopwatch(); // sw constructor
EXIT:
// Here I have my code
sw.Start();
while (sw.ElapsedMilliseconds < 100000)
{
// do nothing, just wait
}
System.Media.SystemSounds.Beep.Play(); // for test
sw.Stop();
goto EXIT;
Use a timer instead of labels and StopWatch. You are doing busy waiting, tying up the CPU in that tight loop.
You start a timer, giving it an interval to fire on (100000 milliseconds), then run your code in the event handler for the Tick event.
See Comparing the Timer Classes in the .NET Framework Class Library in MSDN magazine.
You could use a timer what Oded suggested:
public partial class TestTimerClass : Form
{
Timer timer1 = new Timer(); // Make the timer available for this class.
public TestTimerClass()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Tick += timer1_Tick; // Assign the tick event
timer1.Interval = 1000; // Set the interval of the timer in ms (1000 ms = 1 sec)
timer1.Start(); // Start the timer
}
void timer1_Tick(object sender, EventArgs e)
{
System.Media.SystemSounds.Beep.Play();
timer1.Stop(); // Stop the timer (remove this if you want to loop the timer)
}
}
EDIT: Just want to show you how to make an easy timer if you don't know how to :)
I want to raise a function periodically .
When I finish one function cycle to wait some period of time and only them to start the second run.
I thought to make it like :
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
timer.Elapsed += TimerTick;
private void TimerTick(object sender, EventArgs e)
{
//My functionality
}
But seems that TimerTick is raised every secound and not secound from my last TimerTick run .
How i can solve this one ?
You can use threads:
var thread = new Thread(o => {
while(true)
{
DoTick();
Thread.Sleep(1000);
}
});
You can stop your timer before doing your processing and start it again after it's done:
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
//My functionality
timer.Start();
}
it's also a good idea to put your functionality in a try-catch and call Start() in the finally section. (if this suits you)
Try the following:
private void TimerTick(object sender, EventArgs e)
{
// get the timer that raised this event (you can have multiple
// timers, or the timer obj is out of scope here, so use this):
Timer timer = (Timer) sender;
// disable (or use timer.Stop())
timer.Enabled = false;
// ...
// your code
// ...
// at end, re-enable
timer.Enabled = true;
}
you will find that the timer will now run 1000ms after your code finished. You can also use timer.Stop() and timer.Start().
you could always do something like this:
while (true)
{
// your functions
Thread.Sleep(1000)
}
you'd have to find a way to stop this through an external mechanism, but it should work.
You're right: the timer will run every second: it won't care what you're doing in the TimerTick.
What you can do is to stop the timer on entering the TimerTick methode.
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
//My functionality
timer.Start();
}
Try this:
DateTime lastDT = DateTime.MinValue;
private void TimerTick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
if (now - last).TotalSeconds > what_you_want
{
//My functionality
}
last = now;
}
Using this, your form (main thread) is not locked and you/user can do what you please.
Try
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
// My Functionality
timer.Stop();
}
However, you may have an extra even fired. As per MSDN Docs:
The signal to raise the Elapsed event is always queued for execution on a ThreadPool thread, so the event-handling method might run on one thread at the same time that a call to the Stop method runs on another thread. This might result in the Elapsed event being raised after the Stop method is called. The code example in the next section shows one way to work around this race condition.
You might want to consider Thread.Sleep() instead
I have a timer that needs to not process its elapsed event handler at the same time. But processing one Elapsed event may interfere with others. I implemented the below solution, but something feels wrong; it seems like either I should be using the timer differently or using another object within the threading space. The timer seemed to fit best because I do need to periodically check for a status, but sometimes checking will take longer than my interval. Is this the best way to approach this?
// member variable
private static readonly object timerLock = new object();
private bool found = false;
// elsewhere
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed = Timer_OnElapsed;
timer.Start();
public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
lock(timerLock)
{
if (!found)
{
found = LookForItWhichMightTakeALongTime();
}
}
}
You could set AutoReset to false, then explicitly reset the timer after you are done handling it. Of course, how you handle it really depends on how you expect the timer to operate. Doing it this way would allow your timer to drift away from the actual specified interval (as would stopping and restarting). Your mechanism would allow each interval to fire and be handled but it may result in a backlog of unhandled events that are handled now where near the expiration of the timer that cause the handler to be invoked.
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed += Timer_OnElapsed;
timer.AutoReset = false;
timer.Start();
public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
if (!found)
{
found = LookForItWhichMightTakeALongTime();
}
timer.Start();
}
I usually stop the timer while processing it, enter a try/finally block, and resume the timer when done.
If LookForItWhichMightTakeALongTime() is going to take a long time, I would suggest not using a System.Windows.Forms.Timer because doing so will lock up your UI thread and the user may kill your application thinking that it has frozen.
What you could use is a BackgroundWorker (along with a Timer if so desired).
public class MyForm : Form
{
private BackgroundWorker backgroundWorker = new BackgroundWorker();
public MyForm()
{
InitializeComponents();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted +=
backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = LookForItWhichMightTakeALongTime();
}
private void backgroundWorker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
found = e.Result as MyClass;
}
}
And you can call RunWorkerAsync() from anywhere you want to, even from a Timer if you want. And just make sure to check if the BackgroundWorker is running already since calling RunWorkerAsync() when it's running will throw an exception.
private void timer_Tick(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
backgroundWorker.RunWorkerAsync();
}
timer.enabled = false
or
timer.stop();
and
timer.enabled = true
or
timer.start();
I use the System.Threading.Timer like so
class Class1
{
static Timer timer = new Timer(DoSomething,null,TimeSpan.FromMinutes(1),TimeSpan.FromMinutes(1));
private static void DoSomething(object state)
{
timer = null; // stop timer
// do some long stuff here
timer = new Timer(DoSomething, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
}
}