Note that there are some explanatory texts on larger screens.

plurals
  1. PO"Atomically" changing a System.Threading.Timer
    text
    copied!<p>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:</p> <pre><code>var timer = new Timer(DelayCallback, null, 10000, Timeout.Infinite); // ... (sometime later but before DelayCallback has executed) timer.Change(20000, Timeout.Infinite); </code></pre> <p>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.</p> <p>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.)</p> <p>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 <em>seems</em> less efficient than just changing the existing timer. Of course it <em>may</em> not be...I'll run some micro-benchmarks in a bit and let you all know.</p> <p>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...)</p> <p>My questions are:</p> <ol> <li>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...)</li> <li>Has anyone else implemented (what I term) a "pushback timer" like this? If so, I'd love to hear how you tackled the problem.</li> </ol> <p>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).</p> <p>Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload