I am a beginner with windows forms (visual studio 2010) , and wanted to know is there any way to get the value of a timer at any instant of time ?
For starters i want to lets say display the value of a timer in a text box e.g if my timer is from 0 to 100, i want to show these values 0 to 100 all the way in a textbox.
Secondly, is there a timer variable which may give the number of times my timer has ticked since it was started?
It sounds like you want a Stopwatch, as mentioned in a comment.
You can use the Start command whenever you start the Timer (if you find you even still need that), then check Elapsed when you want to know how long has passed, for instance in the Timer.Tick event.
As for your second question, you'll need a private field to track your tick count, but that's easy enough. Just increment the number on each tick and forget about it. No big deal.
There are multiple ways to solve your problem, partly because it is so open ended.
System.Windows.Forms.Timer
You would need to write an event handler which would be executed whenever the timer ticks. This timer must be hosted on a form.
System.Threading.Timer
You would need to specify a callback delegate which executes when the timer ticks. This doesn't need a form to run.
System.Diagnostics.Stopwatch
This is a class which can be started and stopped, and can tell you the amount of time elapsed since it was started.
System.Threading.Timer example to make a simple counter
Private t As System.Threading.Timer
Private counter As Long = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
t = New System.Threading.Timer(Sub() counter += 1)
t.Change(1000, 1000) ' 1000 (ms): start after 1 second, 1000 (ms): 1 second interval
End Sub
Public ReadOnly Property Counts As Long
Get
Return counter
End Get
End Property
Public Sub ResetCounter()
t.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite)
counter = 0
t.Change(1000, 1000)
End Sub
Related
I'm new to the Bass library but is it possible to pass in a list of times that trigger an event when the song has reached that time? For example, if I set a trigger at 30 seconds, when the song reaches 30 seconds, can I call an event?
I do that using BASS_ChannelSetSync with BASS_SYNC_POS, I use VB not C# but perhaps may help you... and excuse my english
I define a SYNPROC pointing to the the sub that manage the event "time reached"
Private M_SyncMarca As Un4seen.Bass.SYNCPROC = New Un4seen.Bass.SYNCPROC(AddressOf sync_marcas)
Private M_HandlerMarcas As Integer
then, add the reference to your channel
M_HandlerMarcas = Bass.BASS_ChannelSetSync(pista_actual, BASSSync.BASS_SYNC_POS, marca_fin, M_SyncMarca, IntPtr.Zero)
and finaly, the subrutine to manage wath you want when time is reached.
Private Sub sync_marcas()
Me.Invoke(New System.Windows.Forms.MethodInvoker(AddressOf manejar_marca))
End Sub
there where may be painful with threads, that's why I point to another sub rutine.
I hope this can help you
I am currently trying to make a chronometer in c# using the timespan class. So far I have been able to appropriately start, pause, and stop the chronometer, but I have been asked to make a lap button that registers the time in the chronometer upon click, and make another button that opens another form to list said lap times. It is this part that i have trouble with.
Basically I need help with registering the time and retaining those values to later show them in a list. I appreciate your time and willingness to help.
This is some of the code i tried to make for registering the time along with making a different class called LapList, it didnt go very well.
private void button2_Click(object sender, EventArgs e)
{
TimeSpan Et = Crono.Elapsed;
TimeSpan LapTime = Et - LastBreakTime;
LastBreakTime = Et;
++Lapcount;
LapList.getTimeSpan().Add(LapTime);
}
Thanks again for your time.
It seems you should be able to store the DateTime.Now of each click of the Lap button, then use DateTime2 - DateTime1 to give you a TimeSpan object that can be displayed?
So each click of Lap button effectively performs a List.Add(DateTime.Now) and your lap display iterates over the list, performing List[I] - List[I-1]
.NET already has a Stopwatch for measuring time and returning the elapsed time as a TimeSpan, Milliseconds or Ticks.
You can start a new Stopwatch with Stopwatch.StartNew and store the instance in a field until you need to check the elapsed time. You can also pass the instance from method to method, or store it in an array or dictionary so you can time multiple executions
I have a service that is always running, it has a timer to perform a particular action every day at 2AM.
TimeSpan runTime = new TimeSpan(2, 0, 0); // 2 AM
TimeSpan timeToFirstRun = runTime - DateTime.Now.TimeOfDay;
if (timeToFirstRun.TotalHours < 0)
{
timeToFirstRun += TimeSpan.FromDays(1.0);
}
_dailyNodalRunTimer = new Timer(
RunNodalDailyBatch,
null,
timeToFirstRun,
TimeSpan.FromDays(1.0)); //repeat event daily
That initialization code is called once when the service first starts, over the past few days I have logged when the Timer has fired:
2011-05-21 02:00:01.580
2011-05-22 02:00:03.840
...
2011-05-31 02:00:25.227
2011-06-01 02:00:27.423
2011-06-02 02:00:29.847
As you can see its drifting by 2 seconds every day, getting farther and farther from when it was supposed to fire(at 2 AM).
Am I using it wrong or is this Timer not designed to be accurate? I could recreate the timer each day, or have it fire at some small interval and repeatedly check if I want to perform the action, but that seems kind of hacky.
EDIT
I tried using System.Timers.Timer and it appears to have the same issue. The reseting the Interval is because you cant schedule the initial time before the first tick in System.Timers.Timer like you can in System.Threading.Timer
int secondsInterval = 5;
double secondsUntilRunFirstRun = secondsInterval - (DateTime.Now.TimeOfDay.TotalSeconds % secondsInterval);
var timer = new System.Timers.Timer(secondsUntilRunFirstRun * 1000.0);
timer.AutoReset = true;
timer.Elapsed += (sender, e) =>
{
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff"));
if (timer.Interval != (secondsInterval * 1000.0))
timer.Interval = secondsInterval * 1000.0;
};
timer.Start();
Produce the following times, you can see how they are drifting slightly:
06:47:40.020
06:47:45.035
06:47:50.051
...
06:49:40.215
06:49:45.223
06:49:50.232
So I guess the best approach really is to just reschedule the timer in the tick handler? The following produces a tick at a regular interval within ~15 milliseconds
double secondsUntilRunFirstRun = secondsInterval - (DateTime.Now.TimeOfDay.TotalSeconds % secondsInterval);
var timer = new System.Timers.Timer(secondsUntilRunFirstRun * 1000.0);
timer.AutoReset = false;
timer.Elapsed += (sender, e) =>
{
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff"));
timer.Interval = (secondsInterval - (DateTime.Now.TimeOfDay.TotalSeconds % secondsInterval)) * 1000.0;
};
timer.Start();
06:51:45.009
06:51:50.001
...
06:52:50.011
06:52:55.013
06:53:00.001
Don't let timer inaccuracies accumulate. Use the RTC to calculate how many ms remain until the timeout time. Sleep/setInterval to half this time. When the timer fires/sleep returns, use the RTC again to recalculate the interval left and set interval/sleep again to half-life. Repeat this loop until the remaining interval is less than 50ms. Then CPU loop on the RTC until the desired time is exceeded. Fire the event.
Rgds,
Martin
None of the timers in the .NET Framework will be accurate. There are too many variables in play. If you want a more accurate timer then take a look at multimedia timers. I have never used them over longer durations, but I suspect they are still substantially more accurate than the BCL timers.
But, I see no reason that would prohibit you from using the System.Threading.Timer class. Instead of specifying TimeSpan.FromDays(1) use Timeout.Infinite to prevent periodic signaling. You will then have to restart the timer, but you can specify 23:59:58 or 1.00:00:05 for the dueTime parameter depending on what you calculate the next due time to be to have signal at 2:00a.
By the way, the System.Timers.Timer will do no better than System.Threading.Timer. The reason is because the former actually uses the later behind the scenes anyway. System.Timers.Timer just adds a few handy features like auto resetting and marshaling the execution of the Elapsed onto an ISynchronizeInvoke hosted thread (usually a UI thread).
I think you've already realized this but if you want something to fire at a certain time of day (2AM) you'd be better off with a dedicated thread that sleeps, periodically wakes up and looks to see if it's time to run yet. A sleep around 100 milliseconds would be appropriate and would burn virtually no CPU.
Another approach would be that after you've done your daily work, you compute when to next fire based on 2AM tomorrow - DateTime.Current, etc. This may still not be as accurate as you want (I'm not sure) but at least the drift won't get worse and worse and worse.
If you need accurate timing, you'll need System.Timers.Timer class.
Also see this question: .NET, event every minute (on the minute). Is a timer the best option?
From msdn:
System.Threading.Timer is a simple,
lightweight timer ... For server-based timer functionality, you might consider using System.Timers.Timer, which raises events and has additional features.
You can also move it to Windows Task Scheduler
I am creating a clock application in C#.Net.I have images for each digits from 0-9. I have a timer in the main page constructor which ticks every seconds
DispatcherTimer tmr = new DispatcherTimer();
tmr.Interval = TimeSpan.FromSeconds(1);
tmr.Tick += new EventHandler(tmr_Tick);
tmr.Start();
void tmr_Tick(object sender, EventArgs e)
{
dt = DateTime.Now;
UpdateSecondsImages(dt);
}
private void UpdateSecondsImages(DateTime dt)
{
secondSource2 = dt.Second % 10;
secondDigit2.Source = digimgs[secondSource2];
if (secondSource2 == 0)
{
secondSource1 = dt.Second / 10;
secondDigit1.Source = digimgs[secondSource1];
}
if (secondSource1 == 0)
{
UpdateMinuteImages(dt);
}
}
But the problem I am facing now is this code may skip a second for a minute.Please suggest alternate way to make this smooth from a performance point of view.
Simple. When you set a timer to go off every second you are saying, "please sleep for at least 1 second before waking up and notifying me". In reality, you could be sleeping for much longer. Also, different timing APIs have clock drift relative to each other. The clock that timers are based on may not be the same clock that the DateTime.Now is based on.
Think of it like this - let's say you are actually be waking up once every 1.02 seconds.
Hence, every 50 seconds, you'll skip a beat in rendering. For example you'll go from waking up at "49.98" (rendered as "49") and then your next interval you are woken up at "51.00".
The simple workaround is to sleep for sometime less than 1 second. In your case, I suggest sleeping between 500-750 milliseconds instead of a full second. You can simply re-render the same time again in the case where you wakeup within the same second interval. Or as a trivial optimization, just do nothing when you've already woken up an the second count hasn't changed since previous time.
try saying:
tmr.Interval = TimeSpan.FromMilliSeconds(500);
If it's okay to show clock only when they're visible, I'd rather suggest to use CompositionTarget.Render event handler. Get current time in it and update the UI appropriately. This will not only eliminate the error but will let you render milliseconds as well :).
I highly doubt this approach impacts performance (cos() and sin() are damn fast in our days). But even if it will (you are rendering thousands of clocks), you can update UI not on every frame.
Hope this helps.
Yesterday we launched a contest with Ball Watch USA to create watches in Silverlight. I recommend using a Storyboard to rotate the second hand 360 degrees over 1 minute and set the storyboard to repeat forever. Here are some links:
The Contest
A video describing the task
The animation XAML in SL1
Updating the code to SL2
I have a WPF app that uses DispatcherTimer to update a clock tick.
However, after my application has been running for approx 6 hours the clocks hands angles no longer change. I have verified that the DispatcherTimer is still firing with Debug and that the angle values are still updating, however the screen render does not reflect the change.
I have also verified using WPFPerf tools Visual Profiler that the Unlabeled Time, Tick (Time Manager) and AnimatedRenderMessageHandler(Media Content) are all gradually growing until they are consuming nearly 80% of the CPU, however Memory is running stable.
The hHandRT.Angle is a reference to a RotateTransform
hHandRT = new RotateTransform(_hAngle);
This code works perfectly for approx 5 hours of straight running but after that it delays and the angle change does not render to the screen. Any suggestions for how to troubleshoot this problem or any possible solutions you may know of.
.NET 3.5, Windows Vista SP1 or Windows XP SP3 (both show the same behavior)
EDIT: Adding Clock Tick Function
//In Constructor
...
_dt = new DispatcherTimer();
_dt.Interval = new TimeSpan(0, 0, 1);
_dt.Tick += new EventHandler(Clock_Tick);
...
private void Clock_Tick(object sender, EventArgs e)
{
DateTime startTime = DateTime.UtcNow;
TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById(_timeZoneId);
_now = TimeZoneInfo.ConvertTime(startTime, TimeZoneInfo.Utc, tst);
int hoursInMinutes = _now.Hour * 60 + _now.Minute;
int minutesInSeconds = _now.Minute * 60 + _now.Second;
_hAngle = (double)hoursInMinutes * 360 / 720;
_mAngle = (double)minutesInSeconds * 360 / 3600;
_sAngle = (double)_now.Second * 360 / 60;
// Use _sAngle to showcase more movement during Testing.
//hHandRT.Angle = _sAngle;
hHandRT.Angle = _hAngle;
mHandRT.Angle = _mAngle;
sHandRT.Angle = _sAngle;
//DSEffect
// Add Shadows to Hands creating a UNIFORM light
//hands.Effect = textDropShadow;
}
Along the lines of too much happening in the clock tick, I'm currently trying this adjustment to see if it helps. Too bad it takes 5 hours for the bug to manifest itself :(
//DateTime startTime = DateTime.UtcNow;
//TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById(_timeZoneId);
//_now = TimeZoneInfo.ConvertTime(startTime, TimeZoneInfo.Utc, tst);
_now = _now.AddSeconds(1);
You say you're creating an instance of the Clock class each time? Note that timers in .NET will root themselves to keep themselves from being garbage collected. They'll keep on firing until you stop them yourself, and they will keep your Clock objects alive because they are referenced in the timer tick event.
I think what's happening is that with each Clock you create you start another timer. At first you only fire 1 event per second, but then you get add on another timer and get 2 per second, and they continue to accumulate in this way. Eventually you see your Tick handler and AnimatedRenderMessageHandler rising in CPU until they bog down and are unable to update your screen. That would also explain why increasing the frequency of the timer firings made your symptoms appear sooner.
The fix should be simple: just stop or dispose the DispatcherTimer when you are done with your Clock object.
You're assuming it's the DispatcherTimer and focusing totally on that. I personally have a hard time believing it has anything to do with the timer itself, but rather think it has to do with whatever you're doing within the timer tick. Can you tell us more about exactly what is going on each time the timer ticks?
hHandRT.Angle = _hAngle;
mHandRT.Angle = _mAngle;
sHandRT.Angle = _sAngle;
I believe you have to look at your above code once again.
You are setting Angle property of your transform for all 3 transforms even if you dont need them to change every second. Your minute will change for every 60 changes and your hour will change for every 3600 seconds. However you can atleast reduce your changing hours angle for every second.
What is happening here is, whenever you request transform changes to WPF, WPF queues the request to priority dispatch queue and every second you are pushing more changes to be done then it can process. And this is the only reason your CPU usage keeps on increasing instead of memory.
Detailed Analysis:
After looking at your code, I feel your DispatcherTimer_Tick event does too much of calculation, remember Dispatcher thread is already overloaded with lots of things to do like managing event routing, visual update etc, if keep your cpu more busy to do custom task in dispatcher thread that too in every second event, it will definately keep on increasing the queue of pending tasks.
You might think its a small multiplication calculation but for Dispatcher thread it can be costly when it comes to loading timezones, converting time value etc. You should profile and see the tick execution time.
You should use System.Threading.Timer object, that will run on another thread, after every tick event, when you are done with your calculations of final angles required, you can then pass them on to Dispatcher thread.
like,
Dispatcher.BeginInvoke((Action)delegate(){
hHandRT.Angle = _hAngle;
mHandRT.Angle = _mAngle;
sHandRT.Angle = _sAngle;
});
By doing this, you will be reducing workload from dispatcher thread little bit.