Les gros fichiers Microsoft Project MPP et Primavera XER peuvent prendre de quelques secondes à plusieurs minutes à analyser. Pendant ce temps, une application naïve semble figée : aucune barre de progression, aucun texte d’état, rien sur quoi l’utilisateur puisse agir. Toute personne chargeant de grands plannings a besoin d’un moyen d’afficher l’avancement du chargement, ainsi que d’un moyen d’arrêter un chargement qui dure trop longtemps.

Ce guide couvre les deux avec Aspose.Tasks for .NET. Vous allez créer un rappel de progression qui indique la phase actuelle et un pourcentage, l’intégrer au chargement, garder une interface de bureau réactive pendant que l’analyse s’exécute sur un thread en arrière-plan, et annuler un chargement qui dépasse le budget de temps.

Points clés

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) est la seule méthode que vous implémentez pour recevoir la progression du chargement depuis Aspose.Tasks for .NET.
  • ProgressNotificationArgs expose CurrentStepName, CurrentStepProgress (0–100) et EstimatedTotalProgress (0–100).
  • Attachez le rappel avec LoadOptions.ProjectLoadingCallback ; il est pris en charge pour les formats MPP et XER.
  • Notify s’exécute sur le thread de chargement, il faut donc transférer les valeurs vers le thread UI avant de mettre à jour un contrôle.
  • Annulez un chargement lent en définissant LoadOptions.CancellationToken et en appelant Cancel() sur son CancellationTokenSource depuis un autre thread.
  • L’API de progression fonctionne en mode d’évaluation ; une licence ne fait que supprimer les limites de taille de fichier et de sortie.

Nouveau dans la bibliothèque ? La page produit Aspose.Tasks for .NET et la documentation couvrent l’installation et la licence en détail.

Comment surveiller la progression du chargement du projet en C# ?

Implémentez IProgressNotificationCallback, définissez‑le sur LoadOptions.ProjectLoadingCallback et chargez le fichier via le constructeur Project qui accepte LoadOptions. Le code de base fonctionnel se compose de trois parties : une classe de rappel, une instance de LoadOptions et l’appel de chargement.

  • Entrée : un fichier MPP ou XER, par exemple BigProject.mpp
  • Sortie : mises à jour de progression pendant l’analyse — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • Bibliothèque : Aspose.Tasks for .NET
  • Langage : C#
using System;
using Aspose.Tasks;

internal sealed class ConsoleProgressCallback : IProgressNotificationCallback
{
    public void Notify(ProgressNotificationArgs args)
    {
        Console.WriteLine(
            "{0}: step {1}% / total {2}%",
            args.CurrentStepName,
            args.CurrentStepProgress,
            args.EstimatedTotalProgress);
    }
}

internal static class Program
{
    private static void Main()
    {
        // A license is optional here. Uncomment to remove evaluation limits.
        // new License().SetLicense("Aspose.Tasks.lic");

var loadOptions = new LoadOptions
        {
            ProjectLoadingCallback = new ConsoleProgressCallback()
        };

var project = new Project("BigProject.mpp", loadOptions);

Console.WriteLine("Loaded {0} top-level tasks.", project.RootTask.Children.Count);
    }
}

Lorsque le fichier est analysé, Notify s’exécute plusieurs fois et la console affiche la phase et les pourcentages. Après le retour du constructeur, l’objet Project est entièrement chargé et utilisable.

Pourquoi la surveillance de la progression du chargement est‑elle importante pour les gros fichiers ?

Il remplace une pause qui semble non réactive par un retour visuel, ce qui fait la différence entre une application qui paraît cassée et une application qui paraît occupée. Plus le fichier est volumineux, plus l’analyse est longue, et plus un chargement aveugle vous coûte en qualité perçue.

Utilisations concrètes des valeurs de progression :

  • Piloter une barre de progression déterministe à partir de EstimatedTotalProgress au lieu d’afficher un indicateur de progression indéfini.
  • Enregistrer les transitions de CurrentStepName pour identifier quelle phase domine le temps de chargement lors du profilage d’un fichier lent.
  • Maintenir l’interface utilisateur réactive en chargeant sur un thread d’arrière-plan et en publiant la progression sur le thread UI.
  • Afficher la progression par fichier dans un outil batch qui convertit ou migre de nombreux projets en séquence.

Comment installer Aspose.Tasks et configurer le projet?

Ajoutez le package NuGet Aspose.Tasks à un projet .NET 6 ou ultérieur.

dotnet add package Aspense.Tasks

Ou, depuis la console du Gestionnaire de packages Visual Studio :

Install-Package Aspose.Tasks

Le rappel de progression fonctionne sans licence. Si vous devez charger des fichiers dépassant la limite de taille d’évaluation ou traiter sans restrictions d’évaluation, définissez une licence une fois au démarrage :

using Aspose.Tasks;

var license = new License();
license.SetLicense("Aspose.Tasks.lic");

Vous pouvez demander une licence temporaire gratuite depuis la page de licence temporaire Aspose, et en savoir plus sur la bibliothèque sur la page produit Aspose.Tasks for .NET.

Que fournit l’API IProgressNotificationCallback ?

L’API est une interface, une méthode et un type d’argument, tous dans l’espace de noms Aspose.Tasks.

MembreTypeDescription
IProgressNotificationCallback.Notify(ProgressNotificationArgs)voidAppelé pendant les opérations de projet de longue durée pour signaler la progression.
ProgressNotificationArgs.CurrentStepNamestring (get)Nom de la phase actuelle de l’opération.
ProgressNotificationArgs.CurrentStepProgressint (get)Pourcentage estimé d’achèvement pour la phase actuelle, 0–100.
ProgressNotificationArgs.EstimatedTotalProgressint (get)Pourcentage estimé d’achèvement pour l’ensemble de l’opération, 0–100.
LoadOptions.ProjectLoadingCallbackIProgressNotificationCallback (get/set)Le rappel invoqué pendant le chargement. Pris en charge pour MPP et XER.
LoadOptions.CancellationTokenSystem.Threading.CancellationToken (get/set)Jeton utilisé pour annuler un chargement en cours.

ProgressNotificationArgs est scellé et dérive de EventArgs. Ses trois propriétés sont en lecture seule.

Comment implémentez‑vous un rappel de notification de progression ?

Créez une classe qui implémente IProgressNotificationCallback et faites quelque chose d’utile avec les ProgressNotificationArgs dans Notify. Gardez la méthode rapide, car elle s’exécute sur le thread de chargement.

using System;
using Aspose.Tasks;

internal sealed class ConsoleProgressCallback : IProgressNotificationCallback
{
    private int lastTotal = -1;

public void Notify(ProgressNotificationArgs args)
    {
        // Only redraw when the total percentage actually changes.
        if (args.EstimatedTotalProgress == lastTotal)
        {
            return;
        }

lastTotal = args.EstimatedTotalProgress;
        Console.WriteLine("[{0,3}%] {1}", args.EstimatedTotalProgress, args.CurrentStepName);
    }
}

Le garde sur lastTotal évite d’inonder la console de lignes en double lorsque plusieurs appels Notify signalent le même total.

Comment charger un projet avec suivi de progression ?

Définissez ProjectLoadingCallback sur un objet LoadOptions, puis transmettez‑le au constructeur Project. Le chargement s’exécute de manière synchrone ; lorsque le constructeur retourne, l’analyse est terminée.

using System;
using Aspose.Tasks;

internal static class Loader
{
    public static Project Load(string path)
    {
        var loadOptions = new LoadOptions
        {
            ProjectLoadingCallback = new ConsoleProgressCallback()
        };

// Same call for MPP and XER; only the file path changes.
        var project = new Project(path, loadOptions);

Console.WriteLine("Done. Root task children: {0}", project.RootTask.Children.Count);
        return project;
    }
}

Vous essayez cela selon vos propres horaires ? Téléchargez une licence temporaire gratuite pour exécuter des charges sans la limite d’évaluation sur la taille du fichier.

Comment garder une interface utilisateur réactive pendant le chargement ?

Chargez sur un thread d’arrière-plan et transmettez les valeurs de progression au thread UI à l’intérieur du rappel, car Notify s’exécute sur le thread qui a appelé le constructeur Project.

using System.Windows.Forms;
using Aspose.Tasks;

internal sealed class ProgressBarCallback : IProgressNotificationCallback
{
    private readonly ProgressBar bar;

public ProgressBarCallback(ProgressBar bar) => this.bar = bar;

public void Notify(ProgressNotificationArgs args)
    {
        if (bar.InvokeRequired)
        {
            bar.BeginInvoke(() => bar.Value = args.EstimatedTotalProgress);
        }
        else
        {
            bar.Value = args.EstimatedTotalProgress;
        }
    }
}

Dans WPF, utilisez Dispatcher.Invoke ou Dispatcher.BeginInvoke à la place de Control.BeginInvoke.

Comment annuler un chargement de longue durée ?

Définissez LoadOptions.CancellationToken sur un jeton provenant d’un CancellationTokenSource, puis appelez Cancel() sur cette source depuis un autre thread. Aspose.Tasks arrête l’analyse et le constructeur Project lève une exception, il faut donc l’entourer d’un try/catch.

using System;
using System.Threading;
using Aspose.Tasks;

var cts = new CancellationTokenSource();

var loadOptions = new LoadOptions
{
    ProjectLoadingCallback = new ConsoleProgressCallback(),
    CancellationToken = cts.Token
};

// Wire a Cancel button or a timeout to this:
// cts.CancelAfter(TimeSpan.FromSeconds(30));

try
{
    var project = new Project("BigProject.xer", loadOptions);
    Console.WriteLine("Loaded {0} tasks.", project.RootTask.Children.Count);
}
catch (Exception ex)
{
    Console.WriteLine("Load stopped: {0}", ex.Message);
}

Conclusion

Ajouter la progression du chargement à une application Aspose.Tasks for .NET est un petit changement avec un grand effet sur la réactivité perçue. Implémentez IProgressNotificationCallback, assignez‑le à LoadOptions.ProjectLoadingCallback, et lisez CurrentStepName, CurrentStepProgress et EstimatedTotalProgress dans Notify. Ajoutez un CancellationToken lorsque les chargements peuvent durer suffisamment longtemps pour que l’utilisateur souhaite les arrêter.

Explorez la documentation Aspose.Tasks for .NET et la référence API pour aller plus loin, et téléchargez une licence temporaire gratuite pour évaluer sans limites.

FAQs

Ai-je besoin d’une licence payante pour utiliser l’API de notification de progression ? Non. IProgressNotificationCallback fonctionne en mode d’évaluation. Une licence temporaire ou payante ne fait que supprimer les limites d’évaluation sur la taille du fichier et la sortie ; elle ne débloque pas l’API de progression.

Le même rappel fonctionne-t-il pour les fichiers XER ainsi que pour les MPP ?
Oui. LoadOptions.ProjectLoadingCallback est actuellement pris en charge pour les formats MPP et XER. La même implémentation IProgressNotificationCallback gère les deux.

Le rappel de progression est-il thread‑safe ? Notify est invoqué sur le thread qui exécute le chargement, pas sur un thread d’arrière‑plan. Dans une application de bureau, transmettez les valeurs au thread UI avec Control.Invoke ou Dispatcher.Invoke avant de toucher à une barre de progression.

Quelle est la différence entre CurrentStepProgress et EstimatedTotalProgress ?
CurrentStepProgress est le pourcentage d’achèvement pour la phase actuelle du chargement, comme la lecture des tâches ou la lecture des ressources. EstimatedTotalProgress est le pourcentage d’achèvement estimé pour l’ensemble de l’opération. Les deux sont des entiers de 0 à 100.

Puis-je annuler un chargement depuis l’intérieur du rappel ?
Pas depuis Notify directement. À la place, définissez LoadOptions.CancellationToken sur un jeton provenant d’un CancellationTokenSource et appelez Cancel() sur cette source depuis un autre thread. Le constructeur Project s’arrête alors et lève une exception, donc encapsulez‑le dans un try/catch.

L’ajout d’un rappel ralentit-il le chargement ?
Le surcoût du rappel est négligeable car Notify est appelé à un petit nombre de points de contrôle, pas par enregistrement. Gardez cependant la méthode légère, car tout travail que vous effectuez à l’intérieur s’exécute sur le thread de chargement.

En savoir plus