In the context of this and this previously asked questions and also considering this answer I am wondering if in the following c# code access to the local captured variables must be synchronized.
// Let’s say we have two classes Person and Animal that are immutable.
// Then there is some code that instantiates and uses instances of these classes:
public void SomeMethod()
{
Person person = null;
Animal animal = null;
Parallel.Invoke(() => person = CreatePerson(), // some long running creation process
() => animal = CreateAnimal()); // some long running creation process
// person and animal variables are used beyond this point in non-concurrent manner
}
The code above may look as though we are accessing local variables, however considering that behind the scenes local variables are captured in closure and access to those captured variables is happening in different threads I have a feeling that a proper memory barrier is missing.
My question is: Does access to person and animal variables need to be synchronized? If yes, is the following a correct way of doing it or am I overthinking this?
Parallel.Invoke(() => Volatile.Write(ref person, CreatePerson()),
() => Volatile.Write(ref animal, CreateAnimal()));
Update 1
Let me complicate my example a little and explain my thought process.
// Let’s say we have two classes Person and Animal that are immutable.
// Then there is some code that instantiates and uses instances of these classes:
public void SomeMethod()
{
Person person = CreatePersonLight(); // very fast creation process
Animal animal = CreateAnimalLight(); // very fast creation process
if (IsMonday())
{
Parallel.Invoke(() => person = CreatePersonHeavy(), // some long running creation process
() => animal = CreateAnimalHeavy()); // some long running creation process
}
// person.Name and animal.Breed values are used beyond this point in non-concurrent manner
}
As far as I understand there are three threads involved in this code. First thread that executes "SomeMethod", second thread that executes "CreatePersonHeavy", and third thread that executes "CreateAnimalHeavy".
I am reading this article explaining c# memory model and it states that in c# all writes are volatile, but reads are not. I am wondering then if it is possible that results of "CreatePersonLight" be "cached" in first thread and it will not see whatever second thread produced.
Additionally when at the end of SomeMethod I access a property of a person instance (person.Name) would it not be possible to still get a wrong result due to reordering?
Update 2
The question Making variables captured by a closure volatile is certainly related (that's why it is the first link in my original post) but I don't think is the same/duplicate. Besides it suggests that:
...it would appear that there is no way to force volatile semantics onto captured local variables...
which I am not sure is true. That said it does not still answer my question directly whether in the presented here code access to captured variables must be synchronized or not.