Esplorazione di QueueBackgroundWorkItem in ASP.NET e Framework 4.5.2

Esplorazione di QueueBackgroundWorkItem in ASP.NET e Framework 4.5.2

A volte è molto utile per attività di lunga durata che non devono essere completate prima di restituire una risposta all'utente nell'applicazione ASP.NET.

Ma prima del rilascio di .NET 4.5.2 non eravamo sicuri che queste attività fossero eseguite in modo sicuro.

Nelle note sulla versione, QueueBackgroundWorkItem è così sintetizzato:

Il vantaggio è affidabile . Se utilizzi HostingEnvironment coda in un'applicazione ASP.NET, è garantita l'esecuzione sicura di tutte le attività in background .

Come funziona QueueBackgroundWorkItem?, come segue:

using System.Web.Mvc;
using System.Web.Hosting;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            HostingEnvironment.QueueBackgroundWorkItem(clt =>
            {
                //Background task that needs to be performed safely
            });
            return View();
        }

    }
}

Tieni presente che HostingEnvironment.QueueBackgroundWorkItem appartiene a System.Web.Hosting Spazio dei nomi.

Questo metodo definisce due overload:

  • Action
  • Func

In primo luogo , ecco alcuni esempi con Azione sovraccarico :

Definiremo le azioni di lunga durata:un'attività classica e un'attività asincrona:

using System.Web.Mvc;
using System.Web.Hosting;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            HostingEnvironment.QueueBackgroundWorkItem(clt=>
            {
                //Background task that needs to be performed safely
            });
            return View();
        }

        //Action overload's target
        private void LongRunningAction(CancellationToken clt)
        {
            Task.Run(() => { Thread.Sleep(5000);
                             Debug.WriteLine("Action executed"); 
                           });
        }

        //Action overload's target
        private async void LongRunningActionAsync(CancellationToken clt)
        {
            await Task.Run(() => { Thread.Sleep(5000); 
                                   Debug.WriteLine("Action async executed"); 
                                 });
        }
    }
}

Ora vediamo come usarlo:

using System.Web.Mvc;
using System.Web.Hosting;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //Sample 1
            //Action overload
            //with lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                clt => LongRunningAction(clt)
            );

            //Sample 2
            //Action overload
            //without lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                (Action)LongRunningAction
            );

            //Sample 3
            //Action overload
            //with lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                clt => LongRunningActionAsync(clt)
            );

            //Sample 4
            //Action overload
            //without lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                await (Action)LongRunningAction
            );

            return View();
        }

        //Action overload's target
        private void LongRunningAction(CancellationToken clt)
        {
            Task.Run(() => { Thread.Sleep(5000); 
                             Debug.WriteLine("Action executed"); 
                           });
        }

        //Action overload's target
        private async void LongRunningActionAsync(CancellationToken clt)
        {
            await Task.Run(() => { Thread.Sleep(5000); 
                                   Debug.WriteLine("Action async executed"); 
                                 });
        }
    }
}

Come puoi vedere, puoi eseguire Actions, con la sintassi dell'espressione Lambda (esempio 1) o meno (esempio 2)

Puoi anche eseguire azioni asincrone, con la sintassi dell'espressione Lambda (esempio 3) o meno (esempio 4)

In secondo luogo , ecco alcuni esempi con Func sovraccarico :

Definiremo una funzione che restituirà un'attività di lunga durata :

using System.Web.Mvc;
using System.Web.Hosting;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            HostingEnvironment.QueueBackgroundWorkItem(
                clt => { }
            );

            return View();
        }

        //Func overload's target
        private Task LongRunningFunc(CancellationToken clt)
        {
            return Task.Run(() => { Thread.Sleep(5000); 
                                    Debug.WriteLine("Func executed"); 
                                  });
        }
   
    }
}

Vediamo come usarlo :

using System.Web.Mvc;
using System.Web.Hosting;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //Sample 5
            //Func overload
            //With lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                clt => LongRunningFunc(clt)
            );

            //Sample 6
            //Func overload
            //Without lambda expression
            HostingEnvironment.QueueBackgroundWorkItem(
                (Func)LongRunningFunc
            );

            //Sample 7
            //Func overload
            //With lambda expression
            //Accept async / await
            HostingEnvironment.QueueBackgroundWorkItem(
                async clt => await LongRunningFunc(clt)
            );

            return View();
        }

        //Func overload's target
        private Task LongRunningFunc(CancellationToken clt)
        {
            return Task.Run(() => { Thread.Sleep(5000); 
                                     Debug.WriteLine("Func executed"); 
                                  });
        }
   
    }
}

Come puoi vedere, puoi eseguire funzioni, con la sintassi dell'espressione Lambda (esempio 5) o meno (esempio 6)

Puoi anche utilizzare async / await parole chiave per eseguire la funzione (esempio 7)

Riepilogo

Come hai visto, il nuovo QueueBackgroundWorkItem il metodo è molto facile da usare con diversi parametri del delegato. ASP.NET fa il lavoro pesante per noi impedendo a IIS di terminare i processi di lavoro quando sono presenti elementi di lavoro in background in sospeso. Di conseguenza, HostingEnvironment.QueueBackgroundWorkItem è un candidato ideale per la pianificazione di piccoli lavori in background in .NET 4.5.2.

Ho scelto un ASP.NET MVC per questo articolo, ovviamente puoi chiamare il QueueBackgroundWorkItem metodo da un altro tipo di applicazione Web (come WebForm e anche WCF!), questo non è esclusivo di MVC.