Вызов метода asyn c из NavigationManager.LocationChanged - PullRequest
0 голосов
/ 25 мая 2020

Я использую NavigationManager.LocationChanged для захвата строк запроса. После получения значения строки запроса я делаю вызов ajax, который является asyn c. LocationChanged сам по себе является синхронным методом, и похоже, что не существует asyn c версии LocationChanged. И при вызове метода asyn c изнутри LocationChanged значение, установленное методом asyn c, отстает на один шаг.

Вот его воспроизведение:

@page "/investigate"
@implements IDisposable
@inject NavigationManager NM

<h1>Sync: @SyncValue</h1>
<h1>Async: @AsyncValue</h1>
<button @onclick="TriggerLocationChange">Increment</button>

@code {
    private string SyncValue;
    private string AsyncValue;
    private int Counter = 1;

    protected override void OnInitialized()
    {
        NM.LocationChanged += OnLocationChanged;
    }

    public void Dispose()
    {
        NM.LocationChanged -= OnLocationChanged;
    }

    private void OnLocationChanged(object sender, LocationChangedEventArgs args)
    {
        // sync action, just for comparison
        SyncValue = (Counter * 1000).ToString();

        DoSomeAsync();
    }

    private async Task DoSomeAsync()
    {
        // http call to server
        await Task.Delay(1);

        AsyncValue = (Counter * 1000).ToString();
    }

    private void TriggerLocationChange()
    {
        Counter++;
        NM.NavigateTo("investigate?counter=" + Counter);
    }
}

The @AsyncValue отстает на один шаг от @SyncValue.

Как я могу предотвратить отставание метода asyn c при вызове изнутри LocationChanged?

Ответы [ 2 ]

1 голос
/ 25 мая 2020

Пометка метода с помощью asyn c не меняет сигнатуру метода, поэтому вы должны сделать это:

private async void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
   // sync action:
   SyncValue = (Counter * 1000).ToString();

   await DoSomeAsync();
   StateHasChanged();
}

0 голосов
/ 26 мая 2020

После множества проб и ошибок я обнаружил следующее:

  1. Значения параметров маршрута еще не установлены при запуске LocationChanged. Это не показано в моем примере выше, но важно в моем случае. Параметр маршрута можно извлечь из URL-адреса вручную или подождать, пока blazor заполнит параметр маршрута, используя await Task.Delay(1).

  2. Call StateHasChanged() в конце метода asyn c.

  3. Согласно документации мы должны заключить вызов в base.InvokeAsync(() => ...)

После этих изменений OnLocationChanged станет:

private void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
    // ...

    base.InvokeAsync(async () =>
    {
        await Task.Delay(1);  // wait for blazor to populate route parameters
        await DoSomeAsync();
        StateHasChanged();
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...