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:
Runcan be called multiple times (from different threads) and will never be called afterDisposehas been called.Disposewill 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?