Anyone have a good idea for a basic timer in C#? - c#

Does anyone have a good idea for a timer? I've tried using the stopwatch but I must have done something wrong, I simply wish to have a int value go up once per second and have to ability to reset it.
This is my failed piece of code:
//Timer systemet
Stopwatch Timer = new Stopwatch();
Timer.Start();
TimeSpan ts = Timer.Elapsed;
double seconds = ts.Seconds;
//interval
if(seconds >= 8)
{
Text = Text + 1;
Timer.Stop();
}

I see you've tagged this question with XNA and MonoGame. Typically, in game frameworks like this you don't use typical timers and stopwatches.
In MonoGame you would normally do something like this:
private float _delay = 1.0f;
private int _value = 0;
protected override void Update(GameTime gameTime)
{
var deltaSeconds = (float) gameTime.ElapsedGameTime.TotalSeconds;
// subtract the "game time" from your timer
_delay -= deltaSeconds;
if(_delay <= 0)
{
_value += 1; // increment your value or whatever
_delay = 1.0f; // reset the timer
}
}
Of course, this is the absolute simplest example. You can get more fancy and create a custom class to do the same thing. This way you can create multiple timers. There are examples of this in MonoGame.Extended which you're welcome to borrow the code from.

Easiest way is to use System.Timers.Timer.
Example:
using System.Timers;
class Program
{
static void Main(string[] args)
{
Timer t = new Timer(_period);
t.Elapsed += TimerTick;
t.Start();
}
static void TimerTick(Object source, ElapsedEventArgs e)
{
//your code
}
}
If you need more variable Timer, you can use System.Threading.Timer (System.Timers.Timer is basically wrapper around this class).
Example:
using System.Threading;
class Program
{
static void Main(string[] args)
{
Timer t = new Timer(TimerTick, new AutoResetEvent(false), _dueTime, _period);
}
static void TimerTick(Object state)
{
//your code
}
}

Related

Using ThreadPoolTimer with Background Audio UWP

I am making a UWP app using the BackgroundAudioTask. My app is working very well. Now I want to add in a TextBlock the Current position of the Audio played.
I was doing this method before implementing the audio Task:
private TimeSpan TotalTime;
private DispatcherTimer timerRadioTime;
private void radioPlayer_MediaOpened(object sender, RoutedEventArgs e)
{
TotalTime = radioPlayer.NaturalDuration.TimeSpan;
// Create a timer that will update the counters and the time slider
timerRadioTime = new DispatcherTimer();
timerRadioTime.Interval = TimeSpan.FromSeconds(1);
timerRadioTime.Tick += TimerRadioTime_Tick;
timerRadioTime.Start();
}
private void TimerRadioTime_Tick(object sender, object e)
{
//Check if the audio finished calculate it's total time
if (radioPlayer.NaturalDuration.TimeSpan.TotalSeconds > 0)
{
if (TotalTime.TotalSeconds > 0)
{
// Updating timer
TimeSpan currentPos = radioPlayer.Position;
var currentTime = string.Format("{0:00}:{1:00}", (currentPos.Hours * 60) + currentPos.Minutes, currentPos.Seconds);
radioTimerBlock.Text = currentTime;
}
}
}
When I implemented the Background Task it gave me an Exception. After researching I saw a suggestion of using ThreadPoolTimer instead of dispatcherTimer.
I tried writing this code (following this solution: Clock program employing ThreadPoolTimer C# uwp)
ThreadPoolTimer timer;
// for displaying time only
private void CurrentPlayer_MediaOpened(MediaPlayer sender, object args)
{
_clockTimer_Tick(timer);
}
private async void _clockTimer_Tick(ThreadPoolTimer timer)
{
var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
await dispatcher.RunAsync(
CoreDispatcherPriority.Normal, () =>
{
// Your UI update code goes here!
if (CurrentPlayer.NaturalDuration.TotalSeconds > 0)
{
TimeSpan currentPos = CurrentPlayer.Position;
var currentTime = string.Format("{0:00}:{1:00}", (currentPos.Hours * 60) + currentPos.Minutes, currentPos.Seconds);
CurrentPosition.Text = currentTime;
}
});
}
This is obviously not working. The app enters the method without updating my UI. I really don't understand what timer should be. Any Idea on how to make it run?
Solution:
ThreadPoolTimer timer;
// for displaying time only
private void CurrentPlayer_MediaOpened(MediaPlayer sender, object args)
{
timer = ThreadPoolTimer.CreatePeriodicTimer(_clockTimer_Tick, TimeSpan.FromSeconds(1));
}
private async void _clockTimer_Tick(ThreadPoolTimer timer)
{
var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
await dispatcher.RunAsync(
CoreDispatcherPriority.Normal, () =>
{
// Your UI update code goes here!
if (CurrentPlayer.NaturalDuration.TotalSeconds < 0)
{
TimeSpan currentPos = CurrentPlayer.Position;
var currentTime = string.Format("{0:00}:{1:00}", (currentPos.Hours * 60) + currentPos.Minutes, currentPos.Seconds);
CurrentPosition.Text = currentTime;
}
});
}

Why doesn't async work on Elapsed event?

Hi I wanted to call on a subroutine from within a function however it didn't seem possible:
private static void onEnergyTimer(object source, ElapsedEventArgs e)
{
if (energy < pastEnergy - 20) {
StartCoroutine(SendData());}
}
As a work around I tried this but when I try the code below I get the error "unexpected symbol void in class, struct, or interface member declaration"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using UnityEngine;
public class StickTimerBetaCoroutine2 : MonoBehaviour
{
public static float energy = 50.0f;
private static float pastEnergy = energy;
public void Update ()
{
System.Timers.Timer energyTimer = new System.Timers.Timer ();
energyTimer.Elapsed += new ElapsedEventHandler (onEnergyTimer);
energyTimer.Interval = 3000;
energyTimer.Enabled = true;
{
if (JoeysInputStick.flex <= 0) {
energy -= 8 * (Time.deltaTime);
} else if (JoeysInputStick.flex >= 1) {
energy += 2;
} else if (JoeysInputStick.flex >= 2) {
energy += 5;
} else if (JoeysInputStick.flex >= 3) {
energy += 7;
} else if (JoeysInputStick.flex >= 4) {
energy += 9;
} else if (JoeysInputStick.flex >= 5) {
energy += 11;
} else if (JoeysInputStick.flex >= 6) {
energy += 13;
}
}
energy = Mathf.Clamp (energy, 0.0F, 600.0F);
RectTransform rTrans = (RectTransform)transform.GetComponent<RectTransform> ();
rTrans.sizeDelta = new Vector2 (200, energy);
}
private async void onEnergyTimer (object source, ElapsedEventArgs e)
{
if (energy < pastEnergy - 20) {
JoeysInputStick.SendTensOn ();
await Task.Delay (800);
JoeysInputStick.SendTensOff ();
}
pastEnergy = energy;
}
}
Remove Async Keyword
You shouldn't have the async keyword on that function. The Elapsed timer event is not looking for an Async method.
It looks like you wanted to refer directly to the pre-existing private static void onEnergyTimer. I assume you got that code snippet using a decompiler (ilspy or other), and couldn't change that code.
Why async doesn't work on an event handler
Event handlers generally don't support/expect to be calling an async method. I'm not sure, but I think the one you are using uses the Windows Message pump to queue the message to action the Elapsed signal. The Windows Message pump is there so that all UI interactions occur on the Main Thread which owns the control handles.
The async pattern is not for Timers. Instead, if you did want an async equivelent of a delay, you would instead mark the Update function as Async, and then instead of using the Timer and Elapsed function, you would add the lines:
await Task.Delay(3000); //Here's your delay
if (energy < pastEnergy - 20) {
JoeysInputStick.SendTensOn ();
await Task.Delay (800);
JoeysInputStick.SendTensOff ();
}
pastEnergy = energy;
Mark third-party onEnergyTimer function as Public
Rather than implement your own accessible onEnergyTimer function, you could edit the third-party DLL (presumably), changing the function to public. There are many ways to do this, one is to request the third-party to update their accessibility of that function, another technical solution is to use the Mono Cecil library (I can go into more detail if required, just leave a comment) - this would work best if you have control over upgraded DLLs, and if you definitely want their version of that function for consistency.
You're trying to place your method signature outside of any class, where the compiler expects you to be declaring a class, struct, or interface. Move your method inside of your class.
public class MyClass
{
...
private async void onEnergyTimer(object source, ElapsedEventArgs e)
{
if (energy < pastEnergy - 20) {
JoeysInputStick.SendTensOn();
await Task.Delay(800);
JoeysInputStick.SendTensOff();
}
pastEnergy = energy;
}
}
This mistake can often happen because your curly-braces aren't matching properly. If you think your method is declared inside your class, inspect your braces to see if you've got a closing brace } where you didn't mean to.
I got some help with this and it turns out the issue was being caused by the editor (mono develop) and the version of .net that was being used by Unity (game engine). I wasn't able to change either of these factors so we used the code below as a work around:
private Queue energyQueue = new Queue();
private bool tensInAction = false;
private void onEnergyTimer (object source, ElapsedEventArgs e)
{
float maxEnergy = 0;
foreach (System.Object reading in (IEnumerable) energyQueue) {
if ((float) reading > maxEnergy) {
maxEnergy = (float) reading;
}
}
if (energy < maxEnergy - 20 && !tensInAction) {
energyQueue.Clear();
tensInAction = true;
JoeysInputStick.SendTensOn ();
System.Timers.Timer tensTimer = new System.Timers.Timer ();
tensTimer.Elapsed += new ElapsedEventHandler (onTensTimer);
tensTimer.Interval = 800;
tensTimer.Enabled = true;
}
energyQueue.Enqueue(energy);
if (energyQueue.Count > 12) {
energyQueue.Dequeue();
}
}
private void onTensTimer (object source, ElapsedEventArgs e) {
JoeysInputStick.SendTensOff ();
tensInAction = false;
}

Passing a variable to timer_tick

Got a problem at the moment, I'm using a timer to do animations and I want to be able to decide where to start using Start and Stop integers as i'll show below.
private void Button1_Click(object sender, EventArgs e)
{
AnimateKey(0,100);
}
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Enabled = true;
myTimer.Start();
}
private void myTimer_Tick(object sender, EventArgs e)
{
lock (myTimer)
{
int StartingFrame = Start;
int StopFrame = Stop;
etc...etc..
}
}
Now my problem is that I want to pass the values 0 and 100 to the Timer Tick event but I have no idea on how to go about doing it.
How can I get the Integers 0 and 100 from the button click to the timer tick ?
Just use a lambda when defining the tick event handler to close over the parameters you need:
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += (s, args) => myTimer_Tick(Start, Stop);
myTimer.Enabled = true;
myTimer.Start();
}
private void myTimer_Tick(int Start, int Stop)
{
//Do stuff
}
Also note that the Tick event of the Timer that you're using will be fired in the UI thread, so there is no need for a lock; the code is already synchronized.
use a class with all info:
public class TimerInfo
{
public int Start;
public int Stop;
}
store an instance in timer's Tag
myTimer.Tag = new TimerInfo { Start = 0, Stop = 100 };
inside the eventhandler you access this info
myTimer = (Timer)sender;
TimerInfo ti = (TimerInfo)myTimer.Tag;
Somewhat hard to understand what you mean, but let's give it a try.
If you ment you want to pass the integers start and stop to the function TimerTick, you probably dont understand the EventArgs parameter. EventArgs is ment to store the arguements which are relevant to your scenario - and the solution is simple.
class myTimerEventArgs:EventArgs // Declaring your own event arguements which you want to send
{
public int start{get;set;}
public int stop {get;set;}
/*Constructor, etc...*/
}
...
//Making the call inside another class:
myTimer_Tick(this,new myTimerEventArgs(0,100);
However, I could be misunderstanding you; If are talking about counting the ticks until it reaches 100 ticks (/intervals), the solution is a simple function added to the event, which would probably look like this:
int Count = 0;
...
private void Counter(object sender, EventArgs e)
{
Count++;
}
...
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Tick += new EventHandler(Counter);
myTimer.Enabled = true;
myTimer.Start();
while(Count!=100);
myTimer.Stop();
}
Hope I helped, have a nice day :)

c# -- How can I make a microsecond timer?

Can anyone help me?
How can I make a microsecond timer in c#?
Like other timers, I want to do Something in the timer body.
If you are familiar with Stopwatches setting the tick-frequency to micoseconds via:
Stopwatch stopWatch = new Stopwatch();
stopWatch.ElapsedTicks / (Stopwatch.Frequency / (1000L*1000L));
should solve your problem.
Here you can download MicroLibrary.cs:
http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer
Example for your problem:
private int counter = 0;
static void Main(string[] args)
{
Program program = new Program();
program.MicroTimerTest();
}
private void MicroTimerTest()
{
MicroLibrary.MicroTimer microTimer = new MicroLibrary.MicroTimer();
microTimer.MicroTimerElapsed +=
new MicroLibrary.MicroTimer.MicroTimerElapsedEventHandler(OnTimedEvent);
microTimer.Interval = 1000; // Call micro timer every 1000µs (1ms)
microTimer.Enabled = true; // Start timer
System.Threading.Thread.Sleep(2000); //do smth 2 seconds
microTimer.Enabled = false; // Stop timer (executes asynchronously)
Console.ReadLine();
}
private void OnTimedEvent(object sender,
MicroLibrary.MicroTimerEventArgs timerEventArgs)
{
// Do something every ms
Console.WriteLine(++counter);
}
}
}
System.Threading.Thread.SpinWait
is also essential for implementing this 'MicroTimer' lo-level class purpose.

How to trigger an event every specific time interval in C#?

the timer needs to be run as a thread and it will trigger an event every fixed interval of time. How can we do it in c#?
Here's a short snippet that prints out a message every 10 seconds.
using System;
public class AClass
{
private System.Timers.Timer _timer;
private DateTime _startTime;
public void Start()
{
_startTime = DateTime.Now;
_timer = new System.Timers.Timer(1000*10); // 10 seconds
_timer.Elapsed += timer_Elapsed;
_timer.Enabled = true;
Console.WriteLine("Timer has started");
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceStart = DateTime.Now - _startTime;
string output = string.Format("{0},{1}\r\n", DateTime.Now.ToLongDateString(), (int) Math.Floor( timeSinceStart.TotalMinutes));
Console.Write(output);
}
}
Use one of the multiple timers available. Systme.Timer as a generic one, there are others dpending on UI technology:
System.Timers.Timer
System.Threading.Timer
System.Windows.Forms.Timer
System.Web.UI.Timer
System.Windows.Threading.DispatcherTimer
You can check Why there are 5 Versions of Timer Classes in .NET? for an explanation of the differences.
if you need something with mroore precision (down to 1ms) you an use the native timerqueues - but that requies some interop coding (or a very basic understanding of google).
I prefer using Microsoft's Reactive Framework (Rx-Main in NuGet).
var subscription =
Observable
.Interval(TimeSpan.FromSeconds(1.0))
.Subscribe(x =>
{
/* do something every second here */
});
And to stop the timer when not needed:
subscription.Dispose();
Super easy!
You can use System.Timers.Timer
Try This:
class Program
{
static System.Timers.Timer timer1 = new System.Timers.Timer();
static void Main(string[] args)
{
timer1.Interval = 1000;//one second
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
timer1.Start();
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}
static private void timer1_Tick(object sender, System.Timers.ElapsedEventArgs e)
{
//do whatever you want
Console.WriteLine("I'm Inside Timer Elapsed Event Handler!");
}
}

Categories