6 votes

Démarrer une tâche d'arrière-plan en utilisant ASP.Net Core Middleware

J'essaie d'exécuter une tâche asynchrone lors du chargement d'une page en ASP.Net Core, c'est-à-dire que je veux que la tâche s'exécute dès que l'utilisateur se dirige vers la page mais que la page s'affiche avant que la tâche ne soit terminée. Il semble qu'avec ASP.Net Core, vous utilisez un intergiciel pour exécuter de telles tâches. J'ai donc essayé d'ajouter ce qui suit à Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
        {

// Other configurations here
app.Use(async (context, next) =>
            {
                if (context.Request.Path.Value.Contains("PageWithAsyncTask"))
                {
                    var serviceWithAsyncTask = serviceProvider.GetService<IMyService>();
                    await serviceWithAsyncTask .DoAsync();
                }
                await next.Invoke();
            });

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

}

Le problème avec ce qui précède est qu'il y a un retard dans le chargement de la page jusqu'à ce que DoAsync est complet puisque nous n'appelons pas next.Invoke() jusqu'à DoAsync est complet. Comment puis-je mettre en œuvre correctement ce qui précède de sorte que next.Invoke() est appelé immédiatement après que j'ai DoAsync en train de courir ?

15voto

peer Points 11386

Dans ASP.NET Core 2, le IHostedService est conçu pour exécuter vos tâches d'arrière-plan. Enregistrez le IHostedService comme Singleton et il sera automatiquement lancé au démarrage :

mise en œuvre des tâches d'arrière-plan dans les microservices avec le service d'hébergement et le service d'arrière-plan de classe net-core-2-x

asp-net-core-background-processing

5voto

Albert Points 2619

Depuis Asp.Net core 2.1 pour utiliser les tâches d'arrière-plan, il est très pratique d'implémenter IHostedService en dérivant de la BackgroundService classe de base. Voici l'exemple tiré de aquí :

public class MyServiceA : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Console.WriteLine("MyServiceA is starting.");

        stoppingToken.Register(() => Console.WriteLine("MyServiceA is stopping."));

        while (!stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine("MyServiceA is doing background work.");

            await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
        }

        Console.WriteLine("MyServiceA background task is stopping.");
    }
}

Il suffit ensuite de l'enregistrer dans Startup.ConfigureServices :

services.AddSingleton<IHostedService, MyServiceA>();

Et comme Stephen Cleary l'a noté Asp.Net n'est peut-être pas le meilleur endroit pour les tâches d'arrière-plan (par exemple, lorsque l'application est hébergée dans IIS, elle peut être fermée à cause des recycles du pool d'applications), mais pour certains scénarios, elle peut être très bien appliquée.

4voto

Stephen Cleary Points 91731

ASP.NET n'a pas été conçu pour les tâches de fond. I fortement Nous vous recommandons d'utiliser une architecture appropriée, telle que Azure Functions / WebJobs / Worker Roles / services Win32 / etc., avec une file d'attente fiable (Azure Queues / MSMQ / etc.) pour que l'application ASP.NET communique avec son service.

Cependant, si vous vraiment si vous le souhaitez - et si vous êtes prêt à en accepter les risques (en particulier, que votre travail puisse être interrompu), vous pouvez alors utiliser IApplicationLifetime .

3voto

Ron C Points 8275

Au lieu de

await serviceWithAsyncTask .DoAsync();

vous pourriez utiliser

 ThreadPool.QueueUserWorkItem(delegate {
       SomeMethod();
   });

Dans cette approche, un thread supplémentaire sera utilisé à partir du pool de threads, ce qui est bien sûr une exigence si vous voulez que le code s'exécute sur un thread autre que le thread principal :-)

Tout code placé après ce bloc sera exécuté immédiatement. Notez également que si votre processus de serveur web (kestral) est recyclé par IIS ou tout autre proxy inverse que vous utilisez, votre travailleur d'arrière-plan sera immédiatement interrompu. Votre travailleur d'arrière-plan doit donc être écrit de manière défensive en gardant cela à l'esprit.

Veuillez également noter que SomeMethod() n'est pas en soi un async méthode. Mais elle est appelée depuis un thread d'arrière-plan et s'exécute donc de manière asynchrone (c'est-à-dire indépendamment du thread principal).

1voto

Mark Redman Points 10816

Jetez un coup d'œil à HangFire pour gérer le traitement en arrière-plan, qui fonctionne très bien en .Net Core : https://www.hangfire.io/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X