I m reading a MSDN example http://msdn.microsoft.com/en-us/library/system.timers.timer.stop.aspx
In the timer.stop example, i suspected its way of using Interlocked.CompareExchange is not right.
private static void HandleElapsed(object sender, ElapsedEventArgs e)
{
numEvents += 1;
// This example assumes that overlapping events can be
// discarded. That is, if an Elapsed event is raised before
// the previous event is finished processing, the second
// event is ignored.
//
// CompareExchange is used to take control of syncPoint,
// and to determine whether the attempt was successful.
// CompareExchange attempts to put 1 into syncPoint, but
// only if the current value of syncPoint is zero
// (specified by the third parameter). If another thread
// has set syncPoint to 1, or if the control thread has
// set syncPoint to -1, the current event is skipped.
// (Normally it would not be necessary to use a local
// variable for the return value. A local variable is
// used here to determine the reason the event was
// skipped.)
//
int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
if (sync == 0)
{
// No other event was executing.
// The event handler simulates an amount of work
// lasting between 50 and 200 milliseconds, so that
// some events will overlap.
int delay = timerIntervalBase
- timerIntervalDelta / 2 + rand.Next(timerIntervalDelta);
Thread.Sleep(delay);
numExecuted += 1;
// Release control of syncPoint.
syncPoint = 0;
}
else
{
if (sync == 1) { numSkipped += 1; } else { numLate += 1; }
}
}
My question is this block
int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
if (sync == 0)
{
// lots of code here
syncPoint = 0;
}
Should it be like
int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
if (sync == 0)
{
// lots of code here
Interlocked.CompareExchange(ref syncPoint, 0, 1)
}
Because the original assigment syncPoint = 0;
is not thread safe. Am I right?
UPDATE:
I updated the example, i have no question about the return value of ComareExchange, my question is about the the assignment of variable syncpoint in the end of this if block. There is no interlock on it at all.