我正在阅读 MSDN 示例http://msdn.microsoft.com/en-us/library/system.timers.timer.stop.aspx
在 timer.stop 示例中,我怀疑它使用 Interlocked.CompareExchange 的方式不正确。
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; }
}
}
我的问题是这个块
int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
if (sync == 0)
{
// lots of code here
syncPoint = 0;
}
应该像
int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
if (sync == 0)
{
// lots of code here
Interlocked.CompareExchange(ref syncPoint, 0, 1)
}
因为原始分配 syncPoint = 0;
不是线程安全的。我对吗?
更新:
我更新了这个例子,我对 ComareExchange 的返回值没有任何疑问,我的问题是关于这个 if 块末尾的变量同步点的分配。它根本没有联锁。