Ответ 1
По своей сути невозможно, чтобы метод async
a struct
сам мутировал ".
Это, конечно, имеет смысл, когда вы об этом думаете. К тому времени, когда все задачи, которые вы await
внутри этой структуры действительно закончили, учитывая, что вы вернулись к вызывающему абоненту и позволили им продолжать делать всевозможные вещи, у вас нет способа гарантировать, что фактический экземпляр структуры, называемый методом, уже существует. Если SetValueAsync
вызывается в локальной переменной методом, который не использовал await
it или Wait
на нем или что-то в этом роде, то это время жизни локальной переменной, вероятно, закончилось к моменту SetValueAsync
, чтобы продолжить продолжение он вызывает Run
. Он не может мутировать переменную, срок жизни которой может быть или не быть в сфере видимости. Единственный вариант здесь для методов async
структуры, чтобы эффективно копировать себя при вызове метода и иметь код в ссылке продолжения, совершенно другую переменную, которая называется переменной async
. Поскольку метод создает копию, которая не будет доступна нигде, кроме тела этого метода async
, это означает, что для всех целей цели метод async
структуры никогда не сможет мутировать эту структуру (и мутация должна быть видна кем-то еще).
У вас может быть метод async
изменчивого struct
, при условии, что сам этот метод не будет мутировать struct
. Этот один метод должен будет вернуть Task<T>
с новой структурой или чем-то эквивалентным.
Как интересный такет, он в рамках технической возможности для метода async
a struct
мутировать себя перед первым await
метода, если он действительно этого хотел. Компилятор выбирает копию сразу, поэтому на самом деле это невозможно, но явный выбор был сделан, чтобы сделать копию в самом начале метода, а не только после первого await
. Это, вероятно, к лучшему, будь то намеренное решение или нет, так как это было бы супер путать иначе.