I want to create a new dispatcher timer, with different periods each time method foo(30) is called using a timer value:
void foo(int timerValueInSeconds)
{
TimeSpan _DestructionTimer = TimeSpan.FromSeconds(timerValueInSeconds);
DateTime _FullDestructionTimer = DateTime.Now + _DestructionTimer;
DispatcherTimer _DispatcherTimer = new DispatcherTimer();
_DispatcherTimer.Interval = TimeSpan.FromMilliseconds(1000);
_DispatcherTimer.Tick += new EventHandler((sender, e) => DispatcherTimer_Tick(sender, e, _FullDestructionTimer, _NewMessage, _DispatcherTimer));
_DispatcherTimer.Start();
}
private void DispatcherTimer_Tick(object sender, EventArgs e, DateTime timer, Message _message, DispatcherTimer _dispatcherTimer)
{
var remaining = timer - DateTime.Now;
int remainingSeconds = (int)remaining.TotalSeconds;
//update timer in view
_message.Timer.ValueInSeconds = remainingSeconds;
//stop the timer if reach to zero
if (remaining.TotalSeconds <= 0)
{
_dispatcherTimer.Stop();
//remove message from list
}
}
When I call foo(30) three times, I expect each timer should run in a different parallel thread, with its specified period, updating the view after each one is finished independently.
I call foo(30), then wait (for example) 3 seconds, then call foo(30) again. The timer is counting down depending on a previous count down timer value (which is 27s), and then it counts down with same value.
Related
I've created a C# windows form application that uses a timer to clear the input boxes every 5 minutes. There is a label called lblTime that displays the amount of time elapsed at any given point while the application is open.
I would like to be able to disable or pause the Timer (Clock.Enabled = false) with a button click, and have lblTime stay on the amount of time elapsed when the button was clicked. However, due to the way that the elapsedTime variable is calculated (DateTime.Now - startTime), this value carries on changing even after the timer has been disabled.
So, to sum up:
lblTime displays running time as Clock ticks
Clock can be disabled by button click, but lblTime carries on incrementing
lblTime needs to stop on current value on same button click that disables Clock, and then be able to start counting again from that same value.
Code that starts Clock, initialises and updates lblTime is displayed.
Any help would this would be very much appreciated,
Thanks,
Mark
private void btnStart_Click(object sender, EventArgs e)
{
//Timers set to start ticking
Clock.Enabled = true;
startTime = DateTime.Now; //the milisecond that btnStart is clicked
initialiseClock();
initialiseIntervalCounter();
}
private void initialiseClock() //initialisation of Clock Timer
{
Clock = new System.Windows.Forms.Timer();
Clock.Tick += new EventHandler(Clock_Tick); //calls Clock EventHandler
Clock.Interval = 1000; //1 second in miliseconds
Clock.Start();
}
private void Clock_Tick(object sender, EventArgs e) //Clock EventHandler definition
{
updateTimeDisplay();
checkDisplay();
}
private void updateTimeDisplay()
{
elapsedTime = (DateTime.Now - startTime);
lblTime.Text = Convert.ToString(elapsedTime);
}
Use a bool flag and a TimeSpan and a counter for the seconds until the next clearing:
DateTime startTime = DateTime.Now;
TimeSpan elapsed = new TimeSpan(0);
bool running = true;
int clearInSeconds = 300;
private void Clock_Tick(object sender, EventArgs e)
{
// function one: count elapsed running time
if (running) elapsed = elapsed.Add(new TimeSpan(0, 0, 1));
lblTime.Text = startTime.Add(elapsed).ToLongTimeString();
// function two: clear stuff after interval:
if (clearInSeconds-- <= 0)
{
clearInSeconds = 300;
// clear your stuff now
}
}
Use your button click to switch between running and not running. I used a click on the label:
private void lblTime_Click(object sender, EventArgs e)
{
running = !running;
}
Change the method in which the countdown time is used. Use a TimeSpan datatype. Initialize the variable to 5 minutes New TimeSpan(0, 5, 0) and use it instead of a start time and Now().
I have a program that is continuously running.
When I start the program, I have a BackgroundWorker (InitialStart.cs):
BackgroundWorker recordingSyncWorker = new BackgroundWorker();
recordingSyncWorker.DoWork += new DoWorkEventHandler(RecordingSyncCheck);
recordingSyncWorker.WorkerSupportsCancellation = false;
recordingSyncWorker.WorkerReportsProgress = false;
recordingSyncWorker.RunWorkerAsync();
void RecordingSyncCheck(object sender, DoWorkEventArgs e)
{
cHandler ch = new cHandler();
Timer theTimer;
int seconds = 1;
if (taskSeconds != null && taskSeconds != "")
seconds = Convert.ToInt32(taskSeconds);
int milliseconds = seconds * 1000;
theTimer = new Timer(10000);
theTimer.Elapsed += new ElapsedEventHandler(ch.SyncMethod);
theTimer.Interval = milliseconds;
theTimer.Enabled = true;
}
And I have two methods in another class (cHandler.cs):
SyncMethod(object source, System.Timers.ElapsedEventArgs e)
{
// random code
}
private string SDCardCheck(object whatever)
{
//more code
}
SDCardCheck gets called thru WCF, so it's like there is another instance of cHandler.cs running. Is there a way for me to pause the BackgroundWorker when I call SDCardCheck?
Don't use a BackgroundWorker just to start a timer. Starting a timer is not a long running operation; it can be done directly from the UI thread.
Your other method can disable the timer to stop it from firing, and then enable it again to allow it to continue firing, in order to effectively pause its execution.
In this code after starting timer again it starts from the current value instead of the vale it stopped. How to pause this timer?
public Page1()
{
InitializeComponent();
_rnd = new Random();
_timer = new DispatcherTimer();
_timer.Tick += new EventHandler(TimerTick);
_timer.Interval = new TimeSpan(0, 0, 0, 1);
}
void TimerTick(object sender, EventArgs e)
{
var time = DateTime.Now - _startTime;
txtTime.Text = string.Format(Const.TimeFormat, time.Hours, time.Minutes, time.Seconds);
}
public void NewGame()
{
_moves = 0;
txtMoves.Text = "0";
txtTime.Text = Const.DefaultTimeValue;
Scrambles();
while (!CheckIfSolvable())
{
Scrambles();
}
_startTime = DateTime.Now;
_timer.Start();
//GridScrambling.Visibility = System.Windows.Visibility.Collapsed;
}
private void Pause_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
NavigationService.Navigate(new Uri("/Page4.xaml", UriKind.Relative));
_timer.Stop();
}
private void Play_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
_timer.Start();
}
As this says that the Stop method only changes the IsEnabled property and this says that this property only prevents the Tick event to be raised, I don't think that there is a method to simply 'pause' the timer. The best way is to reinitialize the timer each time you have "paused" it, if you really want it to start clean again.
But I do not think that this is you real problem. When you pause your game the timer stops working. When you continue it the timer starts working again. When you now try the calculate the time from THIS moment till the start time, then you make a big mistake: you have to ignore the paused time. Because when you play the game 2s, then pause it for 10s and then continue the game, the timer shows 12s, instead of 2s, doesn't it? Maybe you should store the paused times in a variable and substract that from the real game time.
How to stop a timer after some numbers of ticks or after, let's say, 3-4 seconds?
So I start a timer and I want after 10 ticks or after 2-3 seconds to stop automatically.
Thanks!
You can keep a counter like
int counter = 0;
then in every tick you increment it. After your limit you can stop timer then. Do this in your tick event
counter++;
if(counter ==10) //or whatever your limit is
yourtimer.Stop();
When the timer's specified interval is reached (after 3 seconds), timer1_Tick() event handler will be called and you could stop the timer within the event handler.
Timer timer1 = new Timer();
timer1.Interval = 3000;
timer1.Enabled = true;
timer1.Tick += new System.EventHandler(timer1_Tick);
void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop(); // or timer1.Enabled = false;
}
i generally talking because you didn't mention which timer, but they all have ticks... so:
you'll need a counter in the class like
int count;
which you'll initialize in the start of your timer, and you'll need a dateTime like
DateTime start;
which you'll initialize in the start of your timer:
start = DateTime.Now;
and in your tick method you'll do:
if(count++ == 10 || (DateTime.Now - start).TotalSeconds > 2)
timer.stop()
here is a full example
public partial class meClass : Form
{
private System.Windows.Forms.Timer t;
private int count;
private DateTime start;
public meClass()
{
t = new Timer();
t.Interval = 50;
t.Tick += new EventHandler(t_Tick);
count = 0;
start = DateTime.Now;
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
if (count++ >= 10 || (DateTime.Now - start).TotalSeconds > 10)
{
t.Stop();
}
// do your stuff
}
}
Assuming you are using the System.Windows.Forms.Tick. You can keep track of a counter, and the time it lives like so. Its a nice way to use the Tag property of a timer.
This makes it reusable for other timers and keeps your code generic, instead of using a globally defined int counter for each timer.
this code is quiet generic as you can assign this event handler to manage the time it lives, and another event handler to handle the specific actions the timer was created for.
System.Windows.Forms.Timer ExampleTimer = new System.Windows.Forms.Timer();
ExampleTimer.Tag = new CustomTimerStruct
{
Counter = 0,
StartDateTime = DateTime.Now,
MaximumSecondsToLive = 10,
MaximumTicksToLive = 4
};
//Note the order of assigning the handlers. As this is the order they are executed.
ExampleTimer.Tick += Generic_Tick;
ExampleTimer.Tick += Work_Tick;
ExampleTimer.Interval = 1;
ExampleTimer.Start();
public struct CustomTimerStruct
{
public uint Counter;
public DateTime StartDateTime;
public uint MaximumSecondsToLive;
public uint MaximumTicksToLive;
}
void Generic_Tick(object sender, EventArgs e)
{
System.Windows.Forms.Timer thisTimer = sender as System.Windows.Forms.Timer;
CustomTimerStruct TimerInfo = (CustomTimerStruct)thisTimer.Tag;
TimerInfo.Counter++;
//Stop the timer based on its number of ticks
if (TimerInfo.Counter > TimerInfo.MaximumTicksToLive) thisTimer.Stop();
//Stops the timer based on the time its alive
if (DateTime.Now.Subtract(TimerInfo.StartDateTime).TotalSeconds > TimerInfo.MaximumSecondsToLive) thisTimer.Stop();
}
void Work_Tick(object sender, EventArgs e)
{
//Do work specifically for this timer
}
When initializing your timer set a tag value to 0 (zero).
tmrAutoStop.Tag = 0;
Then, with every tick add one...
tmrAutoStop.Tag = int.Parse(tmrAutoStop.Tag.ToString()) + 1;
and check if it reached your desired number:
if (int.Parse(tmrAutoStop.Tag.ToString()) >= 10)
{
//do timer cleanup
}
Use this same technique to alternate the timer associated event:
if (int.Parse(tmrAutoStop.Tag.ToString()) % 2 == 0)
{
//do something...
}
else
{
//do something else...
}
To check elapsed time (in seconds):
int m = int.Parse(tmrAutoStop.Tag.ToString()) * (1000 / tmrAutoStop.Interval);
at the moment i am using a while (true) loop to do this. I am not very familiar with timers. can someone tell me how i would convert this to work with a timer?
string lyricspath = #"c:\lyrics.txt";
TextReader reader = new StreamReader(lyricspath);
int start = 0;
string[] read = File.ReadAllLines(lyricspath);
string join = String.Join(" ", read);
int number = join.Length;
while (true)
{
Application.DoEvents();
Thread.Sleep(200);
start++;
string str = join.Substring(start, 15);
byte[] bytes = Encoding.BigEndianUnicode.GetBytes(str);
label9.Text = str;
if (start == number - 15)
{
start = 0;
}
}
Why use a timer? I assume this is because you want to have the app remain responsive during such a supposedly long operation. If so cosider using the same sort of code but in a BackgroundWorker.
Also if you do specifically want to use a Timer, beware which one you use; the Systm.Timer invokes its event in a different thread to the one used by the applications hoting form. The Timer in Forms events in the forms thread. You may need to Invoke() the operations in a timer callback that change the label.
Basically, a timer just sits there and counts, and every X milliseconds it "ticks"; it raises an event, which you can subscribe to with a method that does whatever you want done every X milliseconds.
First, all of the variables you will need inside the loop, that come from outside the loop, will need to have "instance scope"; they must be a part of the object that currently has this method, and not "local" variables like they are now.
Then, your current method will need to perform all of the steps prior to the while loop, setting whose "instance" variables I mentioned, and then create and start a Timer. There are several Timers in .NET; the two that would be most useful would likely be either the System.Windows.Forms.Timer or the System.Threading.Timer. This timer will need to be given a handle to the method it should call when it "ticks", and should be told how often to "tick".
Finally, all the code inside the while loop, EXCEPT the calls to Application.DoEvents() and Thread.Sleep(), should be placed in the method that the Timer will run when it "ticks".
Something like this ought to work:
private string[] join;
private int number;
private int start;
private Timer lyricsTimer;
private void StartShowingLyrics()
{
string lyricspath = #"c:\lyrics.txt";
TextReader reader = new StreamReader(lyricspath);
start = 0;
string[] read = File.ReadAllLines(lyricspath);
join = String.Join(" ", read);
number = join.Length;
lyricsTimer = new System.Windows.Forms.Timer();
lyricsTimer.Tick += ShowSingleLine;
lyricsTimer.Interval = 300;
lyricsTimer.Enabled = true;
}
private void ShowSingleLine(object sender, EventArgs args)
{
start++;
string str = join.Substring(start, 15);
byte[] bytes = Encoding.BigEndianUnicode.GetBytes(str);
label9.Text = str;
if (start == number - 15)
{
start = 0;
}
}
This runs every 200 ms. But the suggestion to try Google before asking a question here is a good one.
using Timer = System.Windows.Forms.Timer;
private static readonly Timer MyTimer = new Timer();
...
MyTimer.Tick += MyTimerTask;
MyTimer.Interval = 200; // ms
MyTimer.Enabled = true;
...
private void MyTimerTask(Object o, EventArgs ea)
{
...
}
Simply define a new timer:
Timer timer1 = new Timer();
timer1.Interval = 1; // Change it to any interval you need.
timer1.Tick += new System.EventHandler(this.timer1_Tick);
timer1.Start();
Then define a method that will be called in every timer tick (every [Interval] miliseconds):
private void timer1_Tick(object sender, EventArgs e)
{
Application.DoEvents();
Thread.Sleep(200);
start++;
string str = join.Substring(start, 15);
byte[] bytes = Encoding.BigEndianUnicode.GetBytes(str);
label9.Text = str;
if (start == number - 15)
{
start = 0;
}
}
*Remember to define the variables outside the method so you will be able to access them in the timer1_Tick method.