Я бы все же хотел как-то обновить это значение ссылки, не блокируя мой поток пользовательского интерфейса.для меня звучит неразумно, что это невозможно сделать.
Это невозможно.
Подумайте об этом с точки зрения стека потока.Когда параметр ref
передается методу, параметр может быть записан только в этот кадр стека (или ниже).Тем временем асинхронный код работает путем , возвращая вызывающему методу до завершения операции.Так что здесь непроходимая пропасть: кадр стека должен быть сохранен для записи в ref
, а кадр стека должен быть вытолкнут, чтобы быть асинхронным.Вот почему ref
несовместим с асинхронным кодом.
В общем случае ref
не является указателем.Это логически похоже, но .NET - это «безопасный» язык программирования, и поэтому существует правило «ref
должен жить в стеке»..NET преднамеренно предотвращает такие вещи, как копирование ref
в глобальную переменную, где он может обновляться после извлечения кадра стека.
Существует вероятность того, что вы можете сделать что-то опасное, получив указательк объекту и манипулируя им таким образом (используя unsafe
код), но я бы долго и усердно думал, прежде чем идти по этому маршруту.
Без unsafe
кода ваши варианты:
- Сохраните кадр стека, сделав асинхронный код синхронным.Обратите внимание, что ваш пользовательский интерфейс будет заблокирован.
- Сбросьте кадр стека, сделав код асинхронным.Обратите внимание, что любой код вне этого стекового фрейма (включая асинхронный код) не может обновить этот параметр
ref
.
Конечно, основная проблема заключается в сигнатуре метода Main
.Это просто не имеет смысла.Подпись метода является синхронной, и она должна вернуться, прежде чем пользовательский интерфейс все равно сможет обновить.У него действительно должна быть асинхронная подпись.