Запускать фоновые задачи после RedirectToAction - PullRequest
1 голос
/ 06 марта 2020

У меня есть два следующих метода:

    [HttpPost]
    public async Task<IActionResult> CreateModel(MovieModelVm viewModel)
    {
        var preferences = viewModel.MovieModels.ToDictionary(x => x.MovieId, x => x.Selected);
        await Mediator.Send(new CreatePreferenceCommand { Preferences = preferences });
        _ = GenerateModelAndPredictions();

        return RedirectToAction("Index", "Home");
    }

    private async Task GenerateModelAndPredictions()
    {
        await Mediator.Send(new CreateModelCommand());
        await Mediator.Send(new CreatePredictionRatingCommand());
    }

Чего я хочу добиться, это запустить метод GenerateModelAndPredictions, после RedirectToAction. По сути, я хочу сделать некоторые фоновые вещи, не блокируя пользовательский интерфейс.

В начале выполняется первый вызов этого метода, но он просто прерывается без ошибок. Если я вызываю метод типа await GenerateModelAndPredictions();, все работает нормально.

Я пробовал с ConfigureAwait(false), с Task.Run(() =>GenerateModelAndPredictions()), в основном все, чтобы избежать части ожидания, поэтому я не блокирую Пользовательский интерфейс, но безуспешно.

Я немного покопался, но, похоже, я не оборачиваюсь вокруг него.

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Я нашел другое решение моей проблемы; используя планировщик задач. Я использовал Hangfire для этого сценария. В основном методы, которые я хотел запустить в фоновом режиме, будут выполняться заданием, которое я планирую перед перенаправлением.

BackgroundJob.Enqueue(() => GenerateModelAndPredictions());
0 голосов
/ 09 марта 2020

Чего я хочу добиться, так это запустить метод GenerateModelAndPredictions после RedirectToAction.

Вы можете попытаться создать и использовать фильтр действий для запуска собственного метода после выполнения действия CreateModel и до достижения действия Index, как показано ниже.

public class ActionFilterForCreateModelAction : ActionFilterAttribute
{
    public override async Task OnActionExecutionAsync(ActionExecutingContext context, 
        ActionExecutionDelegate next)
    {
        //before the action executes

        await next();

        //after the action executes

        GenerateModelAndPredictions();
    }

    private async Task GenerateModelAndPredictions()
    {
        await Mediator.Send(new CreateModelCommand());
        await Mediator.Send(new CreatePredictionRatingCommand());
    }
}

Применить к CreateModel действие

[HttpPost]
[ActionFilterForCreateModelAction]
public async Task<IActionResult> CreateModel(MovieModelVm viewModel)
...