According to MSDN, the Stopwatch class instance methods aren't safe for multithreaded access. This can also be confirmed by inspecting individual methods.
However, since I only need simple "time elapsed" timers at several places in my code, I was wondering if it could still be done lockless, using something like:
public class ElapsedTimer : IElapsedTimer
{
/// Shared (static) stopwatch instance.
static readonly Stopwatch _stopwatch = Stopwatch.StartNew();
/// Stopwatch offset captured at last call to Reset
long _lastResetTime;
/// Each instance is immediately reset when created
public ElapsedTimer()
{
Reset();
}
/// Resets this instance.
public void Reset()
{
Interlocked.Exchange(ref _lastResetTime, _stopwatch.ElapsedMilliseconds);
}
/// Seconds elapsed since last reset.
public double SecondsElapsed
{
get
{
var resetTime = Interlocked.Read(ref _lastResetTime);
return (_stopwatch.ElapsedMilliseconds - resetTime) / 1000.0;
}
}
}
Since _stopwatch.ElapsedMilliseconds is basically a call to QueryPerformanceCounter, I am presuming it's safe to be called from multiple threads? The difference with a regular Stopwatch is that this class is basically running all the time, so I don't need to keep any additonal state ("running" or "stopped"), like the Stopwatch does.
(Update)
After the suggestion made by #Scott in the answer below, I realized that Stopwatch provides a simple static GetTimestamp methods, which returns raw QueryPerformanceCounter ticks. In other words, the code can be modified to this, which is thread safe:
public class ElapsedTimer : IElapsedTimer
{
static double Frequency = (double)Stopwatch.Frequency;
/// Stopwatch offset for last reset
long _lastResetTime;
public ElapsedTimer()
{
Reset();
}
/// Resets this instance.
public void Reset()
{
// must keep in mind that GetTimestamp ticks are NOT DateTime ticks
// (i.e. they must be divided by Stopwatch.Frequency to get seconds,
// and Stopwatch.Frequency is hw dependent)
Interlocked.Exchange(ref _lastResetTime, Stopwatch.GetTimestamp());
}
/// Seconds elapsed since last reset
public double SecondsElapsed
{
get
{
var resetTime = Interlocked.Read(ref _lastResetTime);
return (Stopwatch.GetTimestamp() - resetTime) / Frequency;
}
}
}
The idea of this code, to clarify, is:
to have a simple and fast way of checking if time has elapsed since a certain operation/event,
methods should not corrupt state if called from multiple threads,
must be insensitive to OS clock changes (user changes, NTP sync, time zone, etc.)
I would use it similar to this:
private readonly ElapsedTimer _lastCommandReceiveTime = new ElapsedTimer();
// can be invoked by multiple threads (usually threadpool)
void Port_CommandReceived(Cmd command)
{
_lastCommandReceiveTime.Reset();
}
// also can be run from multiple threads
void DoStuff()
{
if (_lastCommandReceiveTime.SecondsElapsed > 10)
{
// must do something
}
}
The only change I would suggest is use Interlocked.Exchange(ref _lastResetTime, _stopwatch.ElapsedTicks); instead of Milliseconds because if you are in high performance mode it is possible to get sub millisecond results from QueryPerformanceCounter.
I would recommend creating multiple instances of the Stopwatch and only reading from it on the same thread.
I don't know what your asynchronous code looks like but in psuedo code I would do either:
Stopwatch watch = Stopwatch.Startnew();
DoAsyncWork((err, result) =>
{
Console.WriteLine("Time Elapsed:" + (watch.ElapsedMilliseconds / 1000.0));
// process results...
});
Or:
public DoAsyncWork(callback) // called asynchronously
{
Stopwatch watch = Stopwatch.Startnew();
// do work
var time = watch.ElapsedMilliseconds / 1000.0;
callback(null, new { time: time });
}
The first example assumes that DoAsyncWork work does the work in a different thread then calls the callback when completed, marshalling back to the callers thread.
The second example assumes the caller is handling the threading and this function does all of the timing itself, passing the result back to the caller.
Related
I have to loop through code for specified time .I achieved it with DateTime
var time=DateTime.Now.AddMinutes((Convert.ToDouble(1)));
while(DateTime.Compare(DateTime.Now, time) <= 0)
{
console.write("some message..")
}
How do i achieve the same with Timer.Timer or thread.timer which is best approach..
Is it possible to write 10 times per sec?
Can anyone suggest. thank you
You could always use StopWatch, which is accurate and most appropriate for your scenario.
Action<long> action = (milliseconds) =>
{
Console.WriteLine("Running for {0}ms", milliseconds);
Stopwatch watch = new Stopwatch();
watch.Start();
while (watch.Elapsed.TotalMilliseconds <= milliseconds)
{
Console.WriteLine("ticks:{0}", DateTime.Now.Ticks);
Thread.Sleep(100);
}
Console.WriteLine("Done");
watch.Stop();
};
Task.Run(() => action(1000));
if you are going to make this work you need to make your program multithreaded,
See System.Threading and System.Threading.Task
Once you have your code executing in it's own thread, (using Thread, Task, Timer or any of the other variations in those namespaces) you can tell it to stop executing for a set amount of time, this is done by calling the Thread.Sleep or Task.Delay methods.
e.g.
Task.Run(()=>
{
do
{
//do something
await Task.Delay(100);
}
while(! exitCondition)
});
however you shouldn't count on this for exact timing as what you are doing is saying to the OS that this thread doesn't need to be executed for that amount of time, it doesn't mean the OS will pass it to the processor immediately on the time running out. depending on how busy the CPU is there can be quite a delay before your thread reaches the top of the waiting to process queue. if the timing is vitally important then i would set a lower time and check the clock before running
static void Main(string[] args)
{
System.Threading.Timer timer = null;
int counts = 0;
timer = new Timer((obj) =>
{
Console.WriteLine(counts);
if (++counts > 10)
timer.Dispose();
}, null, 100, 100);
for (;;) ;
}
will call the method dosomething() after 100ms, every 100ms
in the background, till timer.Dispose() is called;
this implementation will ofc never terminate as it is written here ;)
I've created a watchdog timer (using a System.Windows.Forms.Timer), which triggers if a long period of time expires without receiving a small packet of data:
using System.Windows.Forms;
public class Watchdog
{
private Timer Timer;
public void Go()
{
Timer.Start();
}
public void Reset()
{
Timer.Stop();
Timer.Start();
}
private void OnTimerExpired(object State)
{
Timer.Stop();
DoSomething();
}
public Watchdog()
{
Timer = new Timer();
Timer.Tick += new EventHandler(OnTimerExpired);
Timer.Interval = (1000 * Timeout);
}
}
The main code calls Go(), and then calls Reset() each time a packet is received. If the timer expires, OnTimerExpired() is called.
Since that there may be hundreds of packet receptions per second, and since the main job of the application is to respond to such packets, I'm beginning to wonder if resetting the timer isn't too CPU/OS intensive.
Any idea how calling Timer.Stop()/Timer.Start() this way may impact performance (in terms of latency)?
Use a simple timespan or integer variable as a flag. When the timer ticks, it checks against a Stopwatch object to see how much time has elapsed since the flag was last udpated. If it's longer than your timeout value you trigger your watchdog code.
Now, instead of resetting your timer, other code can just use the stopwatch to update your timespan flag value when a new packet comes in.
You should also either set your timer's tick interval to about 1/2 of what you want the actual timeout duration to be, or have code in the event to set your interval so your next tick event is just a few milliseconds after you would timeout if the connection was severed now. Otherwise you could end up waiting almost twice as long as the timeout duration in the situation where your last packet arrived very soon after a tick event.
Another option, by the way, is to just have a Boolean flag that's set whenever a message comes in. The timer event handler checks that flag and alerts if it's not set. So you have:
private bool GotAMessage = false;
void MessageReceived()
{
// happens whenever a message is received
GotAMessage = true;
}
void OnTimerExpired(object state)
{
if (!GotAMessage)
{
// didn't receive a message in time.
}
GotAMessage = false;
}
A simpler option is to call a method on the WatchDog class that updates a common lastPacketReceived value time a packet is received. Then you only need to start a single timer one time in the WatchDog class that ticks once per timeout interval and compares the current time to the lastPacketReceived value:
public static class WatchDog
{
static object locker = new object();
static long lastPacketReceived;
static Stopwatch stopWatch = new Stopwatch();
static long threshold = 5000;
static WatchDog()
{
Timer watchDogTimer = new Timer(1000);
watchDogTimer.Elapsed += new ElapsedEventHandler(watchDogTimer_Elapsed);
watchDogTimer.Start();
stopWatch.Start();
}
static void watchDogTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (locker)
{
if ((stopWatch.ElapsedMilliseconds - lastPacketReceived) > threshold)
{
// threshold exceeded
}
}
}
public static void PacketReceived()
{
lock (locker)
{
lastPacketReceived = stopWatch.ElapsedMilliseconds;
}
}
}
Any idea how calling Timer.Stop()/Timer.Start()
This way may impact performance (in terms of latency)?
None
The amount of resources required to do this is unlikely to be measured. Unless you have a performance problem, don't try to solve a performance problem, at the very least use software to profile the software to see if its an actual problem.
I have a requirement for a timer that has the following behaviour:
Millisecond accuracy
I want the tick event handler to only be called once the current tick handler has completed (much like the winforms timer)
I want exceptions on the main UI thread not to be swallowed up by the thread timer so this requires Invoke/Send instead of BeginInvoke/Post
I've played around with CreateTimerQueueTimer and had some success but at the same time had problems with code reentrance and/or locks when deleting the timer.
I decided to create my own timer so that I could get a better idea of what is going on under the hood so that I can fix the locking and reentrance problems. My code seems to work fine leading me to believe that I may as well use it. Does it look sound?
I've put in a check if the timer is deleted to make sure that the deletion is complete before the timer can be created again. Does that look ok?
Note: I should say that I call timeBeginPeriod(1) and timeEndPeriod(1) inorder to achieve the millisecond accuracy.
(The following code is converted from vb.net to c#, so apologies for any missed mess-ups}
ETA: I've found a problem with it. If the timer is running at an interval of 1 millisecond, and I call, say, Change(300), it locks up # while (this.DeleteRequest). This
must be because the TimerLoop is in the this.CallbackDelegate.Invoke(null) call.
public class MyTimer : IDisposable
{
private System.Threading.TimerCallback CallbackDelegate;
private bool DeleteRequest;
private System.Threading.Thread MainThread;
public MyTimer(System.Threading.TimerCallback callBack)
{
this.CallbackDelegate = callBack;
}
public void Create(int interval)
{
while (this.DeleteRequest) {
System.Threading.Thread.Sleep(0);
}
if (this.MainThread != null) {
throw new Exception("");
}
this.MainThread = new System.Threading.Thread(TimerLoop);
// Make sure the thread is automatically killed when the app is closed.
this.MainThread.IsBackground = true;
this.MainThread.Start(interval);
}
public void Change(int interval)
{
// A lock required here?
if (!this.IsRunning()) {
throw new Exception("");
}
this.Delete();
this.Create(interval);
}
public void Delete()
{
this.DeleteRequest = true;
}
public bool IsRunning()
{
return (this.MainThread != null) && this.MainThread.IsAlive;
}
private void TimerLoop(object args)
{
int interval = (int)args;
Stopwatch sw = new Stopwatch();
sw.Start();
do {
if (this.DeleteRequest) {
this.MainThread = null;
this.DeleteRequest = false;
return;
}
long t1 = sw.ElapsedMilliseconds;
// I want to wait until the operation completes, so I use Invoke.
this.CallbackDelegate.Invoke(null);
if (this.DeleteRequest) {
this.MainThread = null;
this.DeleteRequest = false;
return;
}
long t2 = sw.ElapsedMilliseconds;
int temp = Convert.ToInt32(Math.Max(interval - (t2 - t1), 0));
sw.Reset();
if (temp > 0) {
System.Threading.Thread.Sleep(temp);
}
sw.Start();
} while (true);
}
// The dispose method calls this.Delete()
}
I would recommend using p/Invoke and using the timers from Win32's Timer Queues:
http://msdn.microsoft.com/en-us/library/ms686796(v=vs.85).aspx
One should be mindful that the managed CLR environment has a lot of non-determinism built into it, garbage collection, for instance. Just because your timer is has a period of 1 millisecond doesn't mean that that is necessarily what happens.
Also, the documentation doesn't mention it, but the callback invoked by the timer must be pinned in memory and not garbage collectable, via a GCHandle or other construct. When a timer (or timers, if you kill off a timer queue), the callback will be executed one last time. Not sure whether that happens by the internal wait expiring, or by signalling the internal event handle.
Execution of DeleteTimerQueueTimer() and DeleteTimerQueueEx() can be made synchronous, so they won't return until all timers have signalled and invoked their last callback, but doing that would be suboptimal.
If you don't pin the callbacks and prevent them from being garbage-collected, things will go swimmingly...most of the time. You'll encounter random exceptions.
Also, the callback should be smart enough to bail out if the timer is being deleted, lest it make reference to something that's already GC'd.
μTimer would be a better example!
You can find it here # https://stackoverflow.com/questions/15725711/obtaining-microsecond-precision-using-net-without-platform-invoke?noredirect=1#comment22341931_15725711
It provides accurate wait times down to 1µs and possibly lower depending on your NIC!
Let me know if you need anything else!
I'm writing trading software and need to QoS one method that should not be executed more often than 10 times per second. As I'm begginer in C# and almost not familar with libraries I would like to double-check if my code is "optimal". I'm using Stopwatch because I don't know any other timers in C#.
Stopwatch updateStopwatch = Stopwatch.StartNew();
private void update()
{
if (updateStopwatch.ElapsedMilliseconds < 100)
{
Console.WriteLine("!skip update " + updateStopwatch.ElapsedMilliseconds);
return;
} else
{
Console.WriteLine("!update");
updateStopwatch.Restart();;
}
// do work here
}
upd Now it seems that Stopwatch is pretty good for this task. However probably it would be too slow, if so probably DateTime would be better. sell also Stopwatch vs. using System.DateTime.Now for timing events
Your technique of using Stopwatch is the best solution to prevent the code from executing more frequently. As others have said, using a Timer is a better solution if you want to make sure that the method is executed on a schedule.
Any approach based on DateTime is fundamentally broken because it will fail when the date changes. This is especially noticeable during the Daylight Saving Time switches. When we "spring ahead", there's the potential of the update running twice in quick succession because the code thinks that it's been an hour since the previous update. That's not too bad. But when we "fall back", the update will be suspended for a full hour because the last update time is set an hour ahead.
The same kind of thing can happen, although not as severely, if your computer is set to update its time periodically from an NTP server. If the time is set ahead, then there is the potential for two updates to happen in quick succession. If the time is set back, there's the potential for updates not to happen for the amount of time the clock was set back.
There are ways around the problem (such as using the absolute value of the number of milliseconds), but then you're just putting a bandage on a broken solution. You shouldn't depend on DateTime for intervals like this because your program isn't in control of the system clock--it can change at any time.
Stopwatch is the only reasonable solution here because it depends on the CPU's performance counter, which only increases. You don't have the problems of somebody setting the counter back, and you don't have the rollover problems you would encounter with something like Environment.TickCount.
There's some idea that Stopwatch incurs a performance penalty that DateTime doesn't. My testing shows that to be untrue.
Stopwatches and timers are fairly expensive objects to use. You could simply hold a DateTime object as a variable and perform a comparison.
DateTime lastCheck = DateTime.Now;
private void update()
{
// DateTime.Subtract returns a TimeSpan
int elapsed = DateTime.Now.Subtract(lastCheck).Milliseconds;
if (elapsed < 100)
{
Console.WriteLine("!skip update " + elapsed.ToString());
return;
} else
{
Console.WriteLine("!update");
lastCheck = DateTime.Now;
}
// do work here
}
I would not use a Stopwatch or anything other Timer-like. Instead just store the time of the method call and only execute the subsequent calls if the difference between the current and the stored time is bigger than 100ms.
You could implement a helper class to do this in a more general way:
public class TimedGate
{
private DateTime m_Last;
private TimeSpan m_Gap;
public TimedGate(TimeSpan gap)
{
m_Gap = gap;
}
public bool TryEnter()
{
DateTime now = DateTime.UtcNow;
if (now.Subtract(m_Last) > m_Gap)
{
m_LastEntered = now;
return true;
}
return false;
}
}
Use it like this:
TimedGate m_UpdateGate = new TimedGate(TimeSpan.FromMilliseconds(100));
private void Update()
{
if (m_UpdateGate.TryEnter())
{
Console.WriteLine("!update");
// do work here
}
else
{
Console.WriteLine("!skip update");
}
}
There is always the System.Timer timer.
That is probably easier to work with than the Stopwatch (which normally is used to measure how long time things take).
Code:
var timer = new System.Timers.Timer();
// Hook up the Elapsed event for the timer using a lambda
timer.Elapsed += (o, e) => Console.WriteLine("Timer elapsed");
// Set the Interval to 100 ms
timer.Interval = 100;
// Start the timer.
timer.Enabled = true;
MSDN docs: http://msdn.microsoft.com/en-us/library/system.timers.timer(v=VS.100).aspx
Let's say I have an existing System.Threading.Timer instance and I'd like to call Change on it to push it's firing time back:
var timer = new Timer(DelayCallback, null, 10000, Timeout.Infinite);
// ... (sometime later but before DelayCallback has executed)
timer.Change(20000, Timeout.Infinite);
I'm using this timer to perform an "idle callback" after a period of no activity. ("Idle" and "no activity" are application-defined conditions in this case...the specifics aren't terribly important.) Every time I perform an "action", I want to reset the timer so that it is always set to fire 10 seconds after that.
However, there is an inherent race condition because when I call Change, I can't tell if the Timer has already fired based on its old settings. (I can, of course, tell if my callback has happened but I can't tell if the CLR's internal timer thread has queued my callback to the threadpool and its execution is imminent.)
Now I know I can call Dispose on the timer instance and re-create it each time I need to "push it back". but this seems less efficient than just changing the existing timer. Of course it may not be...I'll run some micro-benchmarks in a bit and let you all know.
Alternatively, I can always keep track of the expected firing time (via DateTime.Now.AddSeconds(10)) and, if the original Timer fires, ignore it by checking DateTime.Now in the callback. (I have a nagging concern that this may not be 100% reliable on account of the Timer using TimeSpan and my check using DateTime...this may not be an issue but I'm not completely comfortable with it for some reason...)
My questions are:
Is there a good way for me to call Timer.Change and be able to know whether I managed to change it before the callback was queued to the threadpool? (I don't think so, but it doesn't hurt to ask...)
Has anyone else implemented (what I term) a "pushback timer" like this? If so, I'd love to hear how you tackled the problem.
This question is somewhat hypothetical in nature since I already have a couple of working solutions (based on Dispose and based on DateTime.Now)...I'm mainly interested in hearing performance-related suggestions (as I'll be "pushing back" the Timer VERY frequently).
Thanks!
it sounds like what you really want is the application-idle event
System.Windows.Forms.Application.Idle
Im interpreting your questions as a request for an implementatation of the IdleNotifier interface specified below. Also you state that ActionOccured() needs to be fast.
public delegate void IdleCallback();
public interface IdleNotifier
{
// Called by threadpool when more than IdleTimeSpanBeforeCallback
// has passed since last call on ActionOccured.
IdleCallback Callback { set; }
TimeSpan IdleTimeSpanBeforeCallback { set; }
void ActionOccured();
}
I provide an implementation with System.Threading.Timer below.
Important points about the implementation:
We accept that the timer can wake up at any time and make sure this is ok.
Since we assume the timer wakes relatively seldom we can do expensive work at these times.
Since we can do all logic in the timer callback all we need to do to "push the timer" is to remeber when last we pushed it.
Implementation:
public class IdleNotifierTimerImplementation : IdleNotifier
{
private readonly object SyncRoot = new object();
private readonly Timer m_Timer;
private IdleCallback m_IdleCallback = null;
private TimeSpan m_IdleTimeSpanBeforeEvent = TimeSpan.Zero;
// Null means there has been no action since last idle notification.
private DateTime? m_LastActionTime = null;
public IdleNotifierTimerImplementation()
{
m_Timer = new Timer(OnTimer);
}
private void OnTimer(object unusedState)
{
lock (SyncRoot)
{
if (m_LastActionTime == null)
{
m_Timer.Change(m_IdleTimeSpanBeforeEvent, TimeSpan.Zero);
return;
}
TimeSpan timeSinceLastUpdate = DateTime.UtcNow - m_LastActionTime.Value;
if (timeSinceLastUpdate > TimeSpan.Zero)
{
// We are no idle yet.
m_Timer.Change(timeSinceLastUpdate, TimeSpan.Zero);
return;
}
m_LastActionTime = null;
m_Timer.Change(m_IdleTimeSpanBeforeEvent, TimeSpan.Zero);
}
if (m_IdleCallback != null)
{
m_IdleCallback();
}
}
// IdleNotifier implementation below
public void ActionOccured()
{
lock (SyncRoot)
{
m_LastActionTime = DateTime.UtcNow;
}
}
public IdleCallback Callback
{
set
{
lock (SyncRoot)
{
m_IdleCallback = value;
}
}
}
public TimeSpan IdleTimeSpanBeforeCallback
{
set
{
lock (SyncRoot)
{
m_IdleTimeSpanBeforeEvent = value;
// Run OnTimer immediately
m_Timer.Change(TimeSpan.Zero, TimeSpan.Zero);
}
}
}
}
There are many straight-forward performance improvements on this code.
If anyone would be intrested in my first thoughts on this just ask me.
I've actually had to build my own "Timing" class for an MMORPG I've made. It could keep track of over 100,000 "entities" that had timers for processing AI, and other tasks. Based on different actions that could be taken, I would have to momentarily delay an event.
Now, my timing class was completely hand written, so it won't be exactly what you're looking for. But something that you could do that would be similar to the solution I came up with is to do a sort of:
while (sleepyTime > 0)
{
int temp = sleepyTime;
sleepyTime = 0;
Thread.Sleep(temp);
}
// here's where your actual code is.
Then, you can make a "Delay" method that basically just ads to sleepyTime.