Trying to understand .net's memory model when it comes to threading. This question is strictly theoretical and I know it can be resolved in other ways such as using a lock
or marking _task
as volatile
.
Take the following piece of code for example:
class Test
{
Task _task;
int _working = 0;
public void Run()
{
if (Interlocked.CompareExchange(ref _working, 1, 0) == 0)
{
_task = Task.Factory.StartNew(() =>
{
//do some work...
});
_task.ContinueWith(antecendent => Interlocked.Exchange(ref _working, 0));
}
}
public void Dispose()
{
if (Interlocked.CompareExchange(ref _working, _working, 0) == 1)
{
_task.ContinueWith(antecendent => { /*do some other work*/ });
}
}
}
Now make the following assumptions:
Run
can be called multiple times (from different threads) and will never be called afterDispose
has been called.Dispose
will be called exactly once.
Now to my question, will the value of _task
(in the Dispose
method) always be a "fresh" value, meaning will it be read from the "main memory" as opposed to being read from a register? From what I've been reading Interlocked
creates a full fence memory barrier, so I'm assuming _task
will be read from main memory or am I completely off?