I always forget the exact workings of this function. It is a static function from namespace System.Threading with a syntax of
Interlocked.CompareExchange(ref location, newValue, comparand)
location : The destination, whose value is compared with comparand and possibly replaced.
newValue : The value that replaces the destination value if the comparison results in equality.
comparand : The value that is compared to the value at location.
Returns : The original value in location.
Programmatically see it as:
if (location == comparand) location = newValue; return (original location value);In a sentence, compare the value in location with comparand, if they are equal set the value of location to newValue. In all cases return the original value of location An example to protect an area of code without blocking:
volatile int _usingResource = 0;
...
// Only allow one thread to enter but do not queue up other threads
// IF (_usingResource == 0) THEN set _usingResource = 1; ...
if (System.Threading.Interlocked.CompareExchange(ref _usingResource, 1, 0) == 0)
{
try
{
DoSomething();
}
finally
{
// No longer in use, reset it.
// NOTE: Interlocked.Exchange not needed here as this is a write of a literal value!
_usingResource = 0; // or Interlocked.Exchange(ref _usingResource, 0);
}
}
else
{
// Do nothing as the resource is currently in use, however the tread is not blocked.
}
Is almost semantically the equivalent of:
static object Lock = new System.Object();
public int CompareExchange(ref int loc, int value, int comp)
{
Monitor.Enter(Lock);
int ret = loc;
if (ret == comp)
loc = value;
Monitor.Exit(Lock);
return ret;
}
although it does NOT use Monitors internally and following threads are not blocked, they proceed from the end of the if block.There is a good example of this being used in the Windows Service Class Example
No comments:
Post a Comment