Loupe

Exécution de tâches en arrière plan dans une application aspnet avec le .NET Framework 4.5.2

Microsoft a rendu disponible la version 4.5.2 du .NET Framework il y a quelques jours. Parmi les nouveautés, on retrouve notamment la possibilité de lancer des tâches en arrière plan au sein d’une application ASP.NET, à l’aide de l’API HostingEnvironment. Elle permet de mettre des tâches en file d’attente pour exécution et s’assure que celles-ci aient terminées de s’exécuter avant que le pool applicatif IIS se coupe.

Vous pourrez trouver toutes les nouveautés du .NET Framework 4.5.2 sur cette page et les téléchargements des outils associés pour Visual Studio ici.

Après avoir installé les outils de développement, créez un nouveau projet d’application Web dans Visual Studio, en ciblant bien le .NET Framework 4.5.2 :

image_46BAC70C

Pour illustrer la fonctionnalité d’exécution de tâches en arrière plan, j’ai choisi un scénario assez simple : un utilisateur peut envoyer une photo depuis un formulaire, et la génération d’une vignette est déclenchée en tâche de fond. Voilà le helper qui permet de générer la vignette dans une Task :

public class ThumbnailHelper
{
    public static Task CreateThumbnail(string filePath)
    {
        return Task.Factory.StartNew(() =>
        {
            Image originalImage = Bitmap.FromFile(filePath);

            int thumbWidth, thumbHeight;

            thumbWidth = 250;
            thumbHeight = (originalImage.Height * 250) / originalImage.Width;

            Image thumbnail = originalImage.GetThumbnailImage(thumbWidth, thumbHeight, null, IntPtr.Zero);

            string thumbFileName = string.Format("{0}_thumb{1}", Path.GetFileNameWithoutExtension(filePath), Path.GetExtension(filePath));
            string thumbFilePath = Path.Combine(Path.GetDirectoryName(filePath), thumbFileName);

            thumbnail.Save(thumbFilePath);
        });
    }
}

Voilà le code cshtml du formulaire d’envoi de photo :

@{
    ViewBag.Title = "Upload a new picture";
}

<h2>@ViewBag.Title</h2>

@using(Html.BeginForm("Upload", "Picture", FormMethod.Post, new{ enctype = "multipart/form-data"}))
{
    @Html.AntiForgeryToken()
    <div class="form-group">
        <label for="file">Choose a picture</label>
        <input type="file" name="file" id="file" />
    </div>
    <div class="form-group">
        <input type="submit" value="Upload and create thumbnail" class="btn btn-primary"/>
    </div>
}

Et le code du contrôleur MVC associé :

public class PictureController : Controller
{
    public ActionResult Upload()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Upload(HttpPostedFileBase file)
    {
        var appDataPath = Server.MapPath("~/App_Data");
        string filePath = Path.Combine(appDataPath, file.FileName);
        file.SaveAs(filePath);

        HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
        {
            return ThumbnailHelper.CreateThumbnail(filePath);
        });

        return RedirectToAction("Upload");
    }
}

Comme vous pouvez le constater, la classe HostingEnvironment définie une méthode QueueBackgroundItem qui prend soit une Action<CancellationToken>, soit une Func<CancellationToken, Task> en paramètre. C’est ici la deuxième surcharge que j’utilise pour lancer en tâche de fond la génération de la vignette à l’aide du ThumbnailHelper.

Et voilà ! C’est aussi simple que ça : avec ce code, vous êtes sûr que toutes les tâches de générations de vignettes seront bien terminées avant que le pool IIS ne s’arrête !

A bientôt

Julien

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus