c# how to run multiple timer in loop. one timer after another - c#

I want to run timer countdown (DispatchTimer) multiple times in a loop, one after another. I want to wait until one timer stops and then run another one.
I'm gonna try something like this:
public TimeSpan CurrentTimeSpan;
private void RunInterval()
{
for (int i = 0; i < 10; i++)
{
RunTimer(new TimeSpan(0, 0, 0, 30));
}
}
private void RunTimer(TimeSpan Timer)
{
DispatcherTimer timer1 = new DispatcherTimer();
timer1.Interval = new TimeSpan(0, 0, 0, 1);
CurrentTimeSpan = Timer;
timer1.Tick += Timer1OnTick;
}
private void Timer1OnTick(object sender, object o)
{
DispatcherTimer timer = (DispatcherTimer) sender;
CurrentTimeSpan = CurrentTimeSpan.Subtract(timer.Interval);
if (CurrentTimeSpan.TotalSeconds == 0)
{
timer.Stop();
}
}
My problem is that method RunInterval or RunTimer doesn't wait until timer will stop.
What can I do about it?

Maybe something like this?
private int hitCount = 0;
public TimeSpan CurrentTimeSpan;
private void RunInterval()
{
RunTimer(new TimeSpan(0, 0, 0, 30));
}
private void RunTimer(TimeSpan Timer)
{
DispatcherTimer timer1 = new DispatcherTimer();
timer1.Interval = new TimeSpan(0, 0, 0, 1);
CurrentTimeSpan = Timer;
timer1.Tick += Timer1OnTick;
}
private void Timer1OnTick(object sender, object o)
{
DispatcherTimer timer = (DispatcherTimer)sender;
if(hitCount == 10)
{
timer.Tick -= Timer1OnTick
}
CurrentTimeSpan = CurrentTimeSpan.Subtract(timer.Interval);
if (CurrentTimeSpan.TotalSeconds == 0)
{
timer.Stop();
}
}
Instead of looping to create the timers just keep track in the event how many times it's been hit and then unhook the event once that target has been achieved.

Related

label disappears if the countdown timer gets zero

i have a Textblock (tbTime) which shows the countdown timer. when it gets zero, the Textblock (tbTime) shows still the zero values. But i wanna make this Textblock (tbTime) disappear, after the countdown timer reaches to zero.
Could anyone help me, please?
C# Code
public partial class InfoScreen : Window
{
DispatcherTimer timer;
TimeSpan time;
public InfoScreen()
{
InitializeComponent();
AppearingNext();
time = TimeSpan.FromSeconds(10);
timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
tbTime.Text = time.ToString("ss");
if (time == TimeSpan.Zero) timer.Stop();
time = time.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);
if (tbTime.Text == "00") //My code doesn't work!
{
tbTime.Visibility = Visibility.Hidden;
}
}
private async void AppearingNext()
{
await Task.Delay(TimeSpan.FromSeconds(10));
VisbilityPanel.Visibility = Visibility.Visible;
}
private void AgreementClick(object sender, RoutedEventArgs e)
{
var registration = new Reset_Register();
registration.Show();
Close();
}
}
One solution is put your code that hide the textblock inside the callback of the timer:
timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate {
tbTime.Text = time.ToString("ss");
if (tbTime.Text == "00") {
tbTime.Visibility = Visibility.Hidden;
}
if (time == TimeSpan.Zero) timer.Stop();
time = time.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);

Making an alarm with C# to ring on specific constant times, throughout a day

I'm trying to make an alarm to ring on specific times ( for example; every five minutes after 9:30 am till 4 pm). So, I want to write a code that rings in 9:30 and 9:35 and ... . but with every approach ultimately I get an error. in my code I have a string that includes the times, but I cannot use that string or group in a if(...) to make the alarm. it's fine with just one number with var..., where am I wrong?
{
public partial class Form1 : Form
{
System.Timers.Timer timer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += Timer_Elapsed;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime currentTime = DateTime.Now;
string[] DailyTime = { 093000, 093500 };
if (((currentTime.Hour * 10000) + (currentTime.Minute *100) + currentTime.Second) == DailyTime)
{
timer.Stop();
try
{
SoundPlayer player = new SoundPlayer();
player.SoundLocation = #"C:\Windows\Media\Time interval alarm\FiveH.wav";
player.Play();
private void Form1_Load(object sender, EventArgs e)
{
timer = new System.Timers.Timer();
timer.Interval = 1000 * 60 * 5; //5 minutes
timer.Elapsed += Timer_Elapsed;
InitializeTimer(); //this method makes sure the timer starts at the correct time
}
The timer initialization method:
private async void InitializeTimer()
{
while (!timer.Enabled) //keep looping until timer is initialized
{
//if the minute is a multiple of 5 (:00, :05, ...) start the timer
if (DateTime.Now.Minute % 5 == 0 && DateTime.Now.Second == 0)
{
timer.Start();
TriggerAlarm(); //trigger the alarm initially instead of having to wait 5min
}
else
{
await Task.Delay(100);
}
}
}
You could store the times and alarm paths in a dictionary:
Dictionary<TimeSpan, string> dict = new Dictionary<TimeSpan, string>()
{
{ new TimeSpan(9, 30, 0), #"C:\Windows\Media\Time interval alarm\FiveH.wav" },
{ new TimeSpan(9, 35, 0), #"C:\Windows\Media\Time interval alarm\Whatever.wav" },
{ new TimeSpan(9, 40, 0), #"C:\Windows\Media\Time interval alarm\Whatever1.wav" },
{ new TimeSpan(9, 45, 0), #"C:\Windows\Media\Time interval alarm\Whatever2.wav" },
//...
{ new TimeSpan(16, 0, 0), #"C:\Windows\Media\Time interval alarm\Whatever3.wav" }
};
The Timer_Elapsed event, which will trigger every 5 min since the alarm is started
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
TriggerAlarm();
}
The method that plays the sound
private static void TriggerAlarm()
{
TimeSpan alarmTime = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, 0);
if (dict.TryGetValue(alarmTime, out string alarmFile))
{
using (SoundPlayer player = new SoundPlayer(alarmFile))
{
player.Play();
}
}
else
{
//this alarm time is not found in the dictionary,
//therefore, no alarm should be played at this time (e.g. 16:05:00)
}
}

DispatcherTimer to run randomly in WPF

I need to do some stuff in my application while application is running. I put it in dispatcher to work withing given time intervals. But now I want to randomized things.
I want to set random time intervals.
dTSettings.Tick += new EventHandler(dTSettings_Tick);
dTSettings.Interval = new TimeSpan(0, SetRandomTimer(), 0);
dTSettings.Start();
how to do that?
private DispatcherTimer _timer = new DispatcherTimer();
private Random rand = new Random();
public void InitAndStartTimer()
{
_timer.Tick += dispatcherTimer_Tick;
_timer.Interval = TimeSpan.FromSeconds(rand.Next(1, 10)); // From 1 s to 10 s
_timer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
_timer.Interval = TimeSpan.FromSeconds(rand.Next(1, 10)); // From 1 s to 10 s
// Do your work.
}

Timer Implementation not Running every 5 seconds as intended c#

I have the following timer implementation. But the timer is not running every 5 seconds as needed. How can make this run every 5 seconds. At present its running about once in 30 seconds.
private void button1_Click(object sender, RoutedEventArgs e)
{
msgsent = 0;
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 5);
bool isenable = timer.IsEnabled;
timer.Start();
}
private async void timer_Tick(object sender, object e)
{
if (geo == null)
{
geo = new Geolocator();
}
Geoposition posi = await geo.GetGeopositionAsync();
if (posi.Coordinate.Point.Position.Latitude <= 12.9227 && posi.Coordinate.Point.Position.Longitude >= 080.1320)
{
if (msgsent <=1)
{
msgsent = msgsent + 1;
ShowDialog(new MessageDialog("Your Bus has crossed xyz"));
}
}
}
I'll give you a hint. If you understand where each goes, then it should be clear. If not, you will once you get better.
// in the class definition
int msgsent;
Timer timer;
and
// in the constructor
timer = new Timer();
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 5);
and
// in the Button.Click event handler
timer.Start();
and
// in the Timer.Tick event handler
timer.Stop();
/* do your work here */
timer.Start();
There will be further issues when the user is clicking the button while you're doing your work, but that's beyond the scope of this question.

How to calculate that how many times tick event occur?

What I really want to do, I want to calculate that how many times tick event occur. Actually I want to make check on it that if this event occurs 5 time.
Then messagebox should displayed.
Here is my code :
public partial class MainWindow : Window
{
int i = 0;
int points = 0;
int counter = 0;
public MainWindow()
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(this.playMyAudioFile);
TimeSpan ts = dispatcherTimer.Interval = new TimeSpan(0, 0, 2);
dispatcherTimer.Start();
if (counter == 5)
{
dispatcherTimer.Stop();
}
InitializeComponent();
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
// some code
label1.Content = points;
}
}
private void playMyAudioFile(object sender, EventArgs e)
{
Random rd = new Random();
i = rd.Next(1, 26);
mediaElement1.Source = new Uri(#"D:\Project C#\A-Z\" + i + ".mp3");
mediaElement1.Play();
}
}
Using await, instead of a timer, makes this particular task much easier:
public static async Task makeMusic(TimeSpan timespan)
{
for (int i = 0; i < 5; i++)
{
//this assumes you can remove the parameters from this method
playMyAudioFile();
await Task.Delay(timespan);
}
MessageBox.Show("All done!");
}
You can make the count a parameter, if it needs to be configurable, or remove the timespan as a parameter if it need never change.
Servy's solution is a lot cleaner than using a timer. But if you insist on using a timer, I would suggest this:
private int counter = 0;
private Random rd = new Random();
private void playMyAudioFile(object sender, EventArgs e)
{
i = rd.Next(1, 26);
mediaElement1.Source = new Uri(#"D:\Project C#\A-Z\" + i + ".mp3");
mediaElement1.Play();
++counter;
if (counter == 5)
{
dispatcherTimer.Stop();
}
}
I think that the sender is the dispatcher timer, so you can probably write:
var timer = (DispatcherTimer)sender;
timer.Stop();
And, please, replace this:
TimeSpan ts = dispatcherTimer.Interval = new TimeSpan(0, 0, 2);
With:
TimeSpan ts = dispatcherTimer.Interval = TimeSpan.FromSeconds(2);
When I see new TimeSpan(0, 0, 2), I have to think about what that signifies. Is it minutes, seconds, and milliseconds? Days, hours, and minutes? Hours, minutes, and seconds?
TimeSpan.FromSeconds(2), though, is explicit. There is absolutely no ambiguity.

Categories