Побочные эффекты всегда видны в продолжениях задачи? - PullRequest
0 голосов
/ 02 апреля 2020

Побочные эффекты гарантированно видны в продолжениях задачи?

object o = null;
Task.Run (() => o = new object ())
    .ContinueWith (t => o.ToString ());

Продолжение может выполняться в потоке, отличном от первого задания. Если нет никакого ограничения памяти, присвоение o может быть невидимым для продолжения. В этом случае будет выдано исключение NullReferenceException. Есть ли что-нибудь, что уже предотвращает это в приведенном выше примере?

1 Ответ

1 голос
/ 02 апреля 2020

Побочные эффекты гарантированно видны в продолжениях задачи?

Если это "есть какая-то официальная документация от MS где-то, которая так говорит", то я боюсь, что ответ - нет .

На практике продолжения были бы бесполезны, если бы они не могли рассчитывать на возможность наблюдать все эффекты, вызванные выполнением задания, с которого они продолжают 1 .

И . NET Framework 4.8 source , и core clr имеют внутренний метод с именем FinishContinuations, который используется для поиска продолжений, которые есть у объекта Task, и заставить их быть запланированным / выполненным. В обеих реализациях Interlocked.Exchange используется для получения объекта продолжения, и, надеюсь, вы уже знаете, что это накладывает полный барьер памяти.


Я также нашел это Сообщение в блоге (не от MS), который содержит список элементов, которые создают барьеры памяти. Завершения задач есть в списке, но нет никаких ссылок на более авторитетные источники.

Я также проверил BotR , но не смог найти никаких утверждений по этому вопросу.


1 Имея в виду, что мы можем иметь Task.ContinueWith, а не только Task<T>.ContinueWith - т.е. он поддерживает сценарий ios, где ничего не передается напрямую от задачи к продолжению.

...