Blazor работает с виртуальным домом, фреймворк отслеживает изменения и отправляет только изменения, когда основной поток не заблокирован.Вот как я позволяю Blazor сбрасывать изменения в пользовательском интерфейсе:
- Использовать
async
функции. - Вносить изменения в виртуальный домен.
- Разблокировать основной поток (Iиспользуйте
await Task.Delay(1)
) - Продолжите выполнение задачи.
Пример
async Task AsyncLongFunc() // this is an async task
{
spinning=true;
await Task.Delay(1); // changes are flushed
LongFunc(); // usually with a wait ( is a web request)
currentCount++;
spinning=false;
await Task.CompletedTask; // just to avoid non await warning.
}
Как видите, StateHasChanged
- этоне нужно.
Примечание: IDK, если есть более простой или более элегантный способ сделать это.
Эффект:
Полный код страницы (отредактировано, совместимо с netcore3 preview6) :
@page "/counter"
<h1>Counter</h1>
<p>Current count:
@(spinning?"Incrementing .... (the spinning effect)":currentCount.ToString())
</p>
<button class="btn btn-primary"
@onclick="@IncrementCount">Click me</button>
<button class="btn @(spinning?"btn-dark":"btn-primary") "
@onclick="@AsyncLongFunc">Click me Async</button>
@code {
int currentCount = 0;
bool spinning = false;
void IncrementCount()
{
currentCount++;
}
async Task AsyncLongFunc()
{
spinning=true;
await Task.Delay(1);
LongFunc();
currentCount++;
spinning=false;
await Task.CompletedTask;
}
void LongFunc() => Task.Delay(2000).Wait();
}