В контексте this и this ранее заданные вопросы, а также принимая во внимание this answer мне интересно, если в следующем C# код доступа к локальным переменным захваченными должны быть синхронизированы.Доступ к захвачена локальных переменных одновременно
// 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
}
Код выше может выглядеть так, как будто мы доступ к локальным переменным, однако, учитывая, что за кулисами локальные переменные являются captured in closure и доступ к этим захваченных переменных происходит в разных потоках у меня есть ощущение, что надлежащий барьер памяти пропал, отсутствует.
Мой вопрос: Необходимо ли синхронизировать доступ к человеку и переменным животного? Если да, то правильный способ сделать это, или я слишком задумываюсь об этом?
Parallel.Invoke(() => Volatile.Write(ref person, CreatePerson()),
() => Volatile.Write(ref animal, CreateAnimal()));
Update 1
Позвольте мне усложнять мой пример немного, и объяснить мой мыслительный процесс.
// 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
}
Насколько я понимаю, в этом коде задействованы три потока. Первый поток, который выполняет «SomeMethod», второй поток, который выполняет «CreatePersonHeavy», и третий поток, который выполняет «CreateAnimalHeavy».
Я читаю this article, объясняя модель памяти C# и утверждает, что в C# все записи являются изменчивыми, но чтение не является. Я задаюсь вопросом, возможно ли, что результаты «CreatePersonLight» будут «кэшированы» в первом потоке, и он не увидит, какой второй поток был произведен.
Кроме того, когда в конце SomeMethod я могу получить доступ к экземпляру экземпляра person (person.Name), не получилось бы получить неправильный результат из-за reordering?
Update 2
Вопрос Making variables captured by a closure volatile определенно связана (именно поэтому он является первым звеном в моей должности), но я не думаю, что это то же самое/дублировать. Кроме того, он предполагает, что:
... казалось бы, что нет никакого способа, чтобы заставить летучую семантику на захваченном локальных переменные ...
который я не уверен, что это правда. Тем не менее, он не отвечает на мой вопрос напрямую, будь то в представленном здесь кодексе доступ к захваченным переменным должен быть синхронизирован или нет.
Тот факт, что вам не нравится ответ на свой вопрос Безразлично Это не дубликат. Другой вопрос задает то же самое. Тот факт, что вы не верите в ответ (несмотря на отсутствие доказательств в поддержку этой позиции), не делает его не дублируемым. – Servy
@Servy, не поймите меня неправильно, мне нравится [этот вопрос] (http://stackoverflow.com/questions/9413080/making-variables-captured-by-a-closure-volatile) и обсуждаемая в нем тема , Моя интерпретация его применительно к моей ситуации заключается в том, что мне нужен надлежащий барьер памяти. Однако я не уверен на 100%, что моя интерпретация верна. –