web-dev-qa-db-fra.com

Asp.Net tâche longue durée / tâche de fond

Le schéma suivant est-il correct pour implémenter un travail d'arrière-plan de longue durée dans Asp.Net Core? Ou devrais-je utiliser une forme de Task.Run/TaskFactory.StartNew avec TaskCreationOptions.LongRunning option?

    public void Configure(IApplicationLifetime lifetime)
    {
        lifetime.ApplicationStarted.Register(() =>
        {
            // not awaiting the 'promise task' here
            var t = DoWorkAsync(lifetime.ApplicationStopping);

            lifetime.ApplicationStopped.Register(() =>
            {
                try
                {
                    // give extra time to complete before shutting down
                    t.Wait(TimeSpan.FromSeconds(10));
                }
                catch (Exception)
                {
                    // ignore
                }
            });
        });
    }

    async Task DoWorkAsync(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            await // async method
        }
    }
18
ubi

Le schéma suivant est-il correct pour implémenter un travail d'arrière-plan de longue durée dans Asp.Net Core?

Oui, c'est l'approche de base pour démarrer un travail de longue durée sur ASP.NET Core. Vous devriez certainement pas utiliser Task.Run/StartNew/LongRunning - cette approche a toujours été erronée.

Notez que votre travail de longue durée peut être interrompu à tout moment, et c'est normal. Si vous avez besoin d'une solution plus fiable, vous devez disposer d'un système d'arrière-plan distinct en dehors d'ASP.NET (par exemple, fonctions Azure/lambdas AWS). Il existe également des bibliothèques comme Hangfire qui vous offrent certaines fiabilité mais qui ont leurs propres inconvénients.

18
Stephen Cleary

Vérifiez également .NET Core 2.0 IHostedService. Voici le documentation . À partir de .NET Core 2.1, nous aurons BackgroundService classe abstraite. Il peut être utilisé comme ceci:

public class UpdateBackgroundService: BackgroundService
{
    private readonly DbContext _context;

    public UpdateTranslatesBackgroundService(DbContext context)
    {
        this._context= context;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await ...
    }
}

Dans votre startup, il vous suffit d'enregistrer la classe:

public static IServiceProvider Build(IServiceCollection services)
{
    //.....
    services.AddSingleton<IHostedService, UpdateBackgroundService>();
    services.AddTransient<IHostedService, UpdateBackgroundService>();  //For run at startup and die.
    //.....
}
18
Makla