Я также попытался инициализировать в переопределении OnAfterRender (), если в процессе предварительной визуализации создавались двойные экземпляры
Это вызвано предварительным рендерингом, а StateManager
- нет. расположены.
Но вы не можете избежать этого, поместив инициализацию в OnAfterRender()
. Самый простой способ - использовать вместо него RenderMode.Server
.
<app>
<strike>@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))</strike>
<b>@(await Html.RenderComponentAsync<App>(RenderMode.Server))
</app></b>
Поскольку для вашего StateManager
требуется знание StateManagerEx
, давайте сначала возьмем в качестве пустышки StateManagerEx
пример, который проще, чем ваш сценарий:
public class StateManagerEx
{
public StateManagerEx()
{
this.Id = Guid.NewGuid().ToString();
}
public string Id { get; private set; }
}
Когда вы отображаете его в Layout
в RenderMode.Server
Mode:
<p> @StateManagerEx.Id </p>
Вы получите Id только один раз. Однако, если вы отобразите его в режиме RenderMode.ServerPrerendered
, вы обнаружите, что:
- Когда браузер отправляет запрос на сервер (но до того, как соединение Blazor было установлено), сервер предварительно отображаетПриложение и возвращает ответ HTTP. Это первый раз, когда создается
StateManagerEx
. - И затем после установления соединения
Blazor
создается еще одно StateManagerEx
.
Я создаю запись экрана и увеличиваю длительность каждого кадра на +100ms
, вы можете видеть, что его поведение точно такое же, как мы описали выше (Идентификатор изменяется):
То же самое касается StateManager
. Когда вы выполняете рендеринг в режиме ServerPrerendered
, будет два StateManager
, один из которых будет создан до того, как будет установлено соединение Blazor, а другой будет находиться в цепи. Таким образом, вы увидите два запущенных экземпляра.
Если я запускаю Initialize (), появляется новый экземпляр, и каждый раз, когда я запускаю Initialize (), создаются новые экземпляры, и все они записывают в консоль своиуникальные идентификаторы.
Всякий раз, когда вы запускаете Initialize()
, создается новый Guid
. Однако экземпляр StateManager
сохраняет то же самое (в то время как StateManager.Id
изменяется на Initialize()
).
Есть что-то, с чем я не справляюсь должным образом?
Ваш StateManager
не реализовал IDisposable
. Если я изменю класс следующим образом:
public class StateManager : IDisposable
{
...
}
, даже если я рендерим App
в режиме ServerPrerendered
, на одно соединение одновременно будет только один 91238a28-9332-4860-b466-a30f8afa5173 checking in...
: