CancellationToken на страницах Blazor? - PullRequest
0 голосов
/ 21 июня 2020

Прожив под камнем в течение 2 лет с умом, я теперь столкнулся с Blazor на моем новом рабочем месте, и мне нужно много наверстать после того, как я сделал в основном ASP. NET Framework MVC до 2 года.

Пробуя себя на стороне сервера Blazor, я попытался применить свои прошлые знания, которые включали токены отмены для операций asyn c, и я не смог найти много информации о них в сочетании с Blazor.

Являются ли они по-прежнему лучшей практикой или в какой-то момент устарели? Я нашел этот ранее заданный вопрос , который рекомендует создать источник токенов для метода OnInitializedAsync() и отменить его на Dispose(), что я, честно говоря, считаю немного грубым. (Мне нужно было бы реализовать это для каждой страницы, и вы знаете ... DRY)

Я также нашел эту статью о расширенном сценарии ios в Microsoft Docs , в которой объясняется, как реализовать Circuit Handler, что, честно говоря, сейчас немного выше меня и, скорее всего, выходит за рамки моего маленького домашнего проекта.

Для сравнения, в asp. net Framework MVC i построит такой контроллер:

namespace SampleWebsite.Controllers
{
    public class SampleController : ApiController
    {
        private readonly MyEntities _entities = new MyEntities();

        public async Task<IHttpActionResult> MyAsyncApi(CancellationToken cancellationToken)
        {
            var result = _entities.MyModel.FirstOrDefault(e => e.Id == 1, cancellationToken: cancellationToken);
            return OK(result);
        }
    }
}

CancellationToken будет внедрен asp. net Framework / Core и напрямую связан с текущим каналом подключения контекста. Следовательно, если пользователь закрывает соединение, токен становится недействительным.

Я бы предположил, что для asp. net core и blazor, где инъекции зависимостей составляют большую часть, это будет случай и здесь, но я не смог найти здесь никакой документации по этому поводу.

Итак, должны ли токены отмены все еще использоваться на этом этапе или Microsoft делает некоторые магические c в фоновом режиме для асинхронных задач? И если да, то какая будет лучшая реализация?

EDIT: Вот моя настройка, чтобы уточнить:

Blazor-Component:

@page "/Index"
@inject IIndexService Service

@* Some fancy UI stuff *@

@code {
    private IEnumerable<FancyUiValue> _uiValues;

    protected override async Task OnInitializedAsync()
    {
        _uiValues = await Service.FetchCostlyValues();
    }
}

И внедренный класс обслуживания, который выполняет тяжелую работу:

public interface IIndexService
{
    Task<IEnumerable<FancyUiValue>> FetchCostlyValues();
}

public class IndexService : IIndexService
{
    public async Task<IEnumerable<FancyUiValue>> FetchCostlyValues()
    {
        var uiValues = await heavyTask.ToListAsync(); // <-- Best way to get a cancellationtoken here?
        return uiValues;
    }
}

Мой вопрос в том, как лучше всего получить токен в определенной части кода, или это будет неактуально потому что Сервер убьет все запущенные задачи, когда соединение (например) закончится?

1 Ответ

1 голос
/ 21 июня 2020

CancellationToken - это лучшая практика на сервере, но обычно он вам не нужен на уровне пользовательского интерфейса. required не должен быть частью уровня пользовательского интерфейса.

Если вам действительно нужен токен, создайте Source с using(...) {...} вокруг этого действия c. Время жизни источника не связано со временем жизни вашей страницы, поэтому страница Dispose () не подходит.

Ваш собственный примерный случай:

protected override async Task OnInitializedAsync()
{
    _uiValues = await Service.FetchCostlyValues();
}

Это либо завершится успешно, либо вызовет исключение. Единственное использование cancelToken - это токен с ограничением времени ожидания.

protected override async Task OnInitializedAsync()
{
   using (var source = new CancelationTokenSource(100))
   {
     _uiValues = await Service.FetchCostlyValues(source.Token);
   }
}

или Microsoft делает какие-то магические c в фоновом режиме для асинхронных задач?

...