I file di grandi dimensioni Microsoft Project MPP e Primavera XER possono richiedere da pochi secondi a diversi minuti per l’analisi. Durante questo tempo, un’applicazione ingenua sembra bloccata: nessuna barra di avanzamento, nessun testo di stato, nulla su cui l’utente possa agire. Chi carica grandi programmi deve disporre di un modo per mostrare a che punto è il caricamento e di un modo per interrompere un’operazione che dura troppo.

Questa guida copre entrambi con Aspose.Tasks for .NET. Creerai un callback di avanzamento che riporta la fase corrente e una percentuale, lo collegherai al caricamento, manterrai l’interfaccia desktop reattiva mentre l’analisi viene eseguita in un thread in background, e annullerai un caricamento che supera il budget di tempo.

Punti chiave

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) è il metodo unico che implementi per ricevere il progresso di caricamento da Aspose.Tasks for .NET.
  • ProgressNotificationArgs espone CurrentStepName, CurrentStepProgress (0–100) e EstimatedTotalProgress (0–100).
  • Collega il callback con LoadOptions.ProjectLoadingCallback; è supportato per i formati MPP e XER.
  • Notify viene eseguito sul thread di caricamento, quindi trasmetti i valori al thread UI prima di aggiornare un controllo.
  • Annulla un caricamento lento impostando LoadOptions.CancellationToken e chiamando Cancel() sul suo CancellationTokenSource da un altro thread.
  • L’API di progresso funziona in modalità di valutazione; una licenza rimuove solo i limiti di dimensione del file e di output.

Nuovo alla libreria? La Aspose.Tasks for .NET pagina del prodotto e la documentazione coprono l’installazione e la licenza in modo completo.

Come monitorare l’avanzamento del caricamento del progetto in C#?

Implementa IProgressNotificationCallback, impostalo su LoadOptions.ProjectLoadingCallback e carica il file tramite il costruttore Project che accetta LoadOptions. Il codice minimo funzionante è composto da tre parti: una classe di callback, un’istanza di LoadOptions e la chiamata di caricamento.

  • Input: un file MPP o XER, ad esempio BigProject.mpp
  • Output: aggiornamenti di avanzamento durante l’analisi — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • Libreria: Aspose.Tasks for .NET
  • Linguaggio: 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);
    }
}

Man mano che il file viene analizzato, Notify viene eseguito più volte e la console mostra la fase e le percentuali. Dopo che il costruttore restituisce, l’oggetto Project è completamente caricato e utilizzabile.

Perché il monitoraggio del progresso di caricamento è importante per i file di grandi dimensioni?

Sostituisce una pausa dall’aspetto non reattivo con un feedback visibile, che è la differenza tra un’applicazione che sembra rotta e una che sembra occupata. Più grande è il file, più lungo è l’analisi e più un caricamento cieco ti costa in termini di qualità percepita.

Usi concreti per i valori di avanzamento:

  • Guidare una barra di avanzamento deterministica da EstimatedTotalProgress invece di mostrare un indicatore di caricamento indefinito.
  • Registrare le transizioni di CurrentStepName per scoprire quale fase domina il tempo di caricamento quando si profila un file lento.
  • Mantenere l’interfaccia utente reattiva caricando su un thread in background e inviando i progressi al thread UI.
  • Mostrare il progresso per file in uno strumento batch che converte o migra molti progetti in sequenza.

Come installare Aspose.Tasks e configurare il progetto?

Aggiungi il pacchetto NuGet Aspose.Tasks a un progetto .NET 6 o successivo.

dotnet add package Aspose.Tasks

Oppure, dalla console del gestore di pacchetti di Visual Studio:

Install-Package Aspose.Tasks

La callback di avanzamento funziona senza licenza. Se è necessario caricare file oltre il limite di dimensione di valutazione o elaborare senza restrizioni di valutazione, impostare una licenza una volta all’avvio:

using Aspose.Tasks;

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

Puoi richiedere una licenza temporanea gratuita dalla pagina di licenza temporanea di Aspose, e leggere ulteriori informazioni sulla libreria nella pagina del prodotto Aspose.Tasks for .NET.

Cosa fornisce l’API IProgressNotificationCallback?

L’API è un’interfaccia, un metodo e un tipo di argomento, tutti nello spazio dei nomi Aspose.Tasks.

MembroTipoDescrizione
IProgressNotificationCallback.Notify(ProgressNotificationArgs)voidChiamato durante operazioni di progetto a lungo termine per segnalare l’avanzamento.
ProgressNotificationArgs.CurrentStepNamestring (get)Nome della fase corrente dell’operazione.
ProgressNotificationArgs.CurrentStepProgressint (get)Percentuale stimata di completamento per la fase corrente, 0–100.
ProgressNotificationArgs.EstimatedTotalProgressint (get)Percentuale stimata di completamento per l’intera operazione, 0–100.
LoadOptions.ProjectLoadingCallbackIProgressNotificationCallback (get/set)Il callback invocato durante il caricamento. Supportato per MPP e XER.
LoadOptions.CancellationTokenSystem.Threading.CancellationToken (get/set)Token utilizzato per annullare un caricamento in corso.

ProgressNotificationArgs è sealed e deriva da EventArgs. Tutte e tre le sue proprietà sono read‑only.

Come implementare un callback di notifica di avanzamento?

Crea una classe che implementa IProgressNotificationCallback e fai qualcosa di utile con ProgressNotificationArgs all’interno di Notify. Mantieni il metodo veloce, perché viene eseguito sul thread di caricamento.

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);
    }
}

Il controllo su lastTotal evita di intasare la console con righe duplicate quando più chiamate a Notify riportano lo stesso totale.

Come caricare un progetto con monitoraggio dell’avanzamento?

Imposta ProjectLoadingCallback su un oggetto LoadOptions, quindi passalo al costruttore Project. Il caricamento viene eseguito in modo sincrono; quando il costruttore restituisce, l’analisi è completa.

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;
    }
}

Stai provando questo secondo i tuoi orari? Scarica una licenza temporanea gratuita per eseguire carichi senza il limite di valutazione sulla dimensione del file.

Come mantenere un’interfaccia utente reattiva durante il caricamento?

Carica su un thread in background e trasferisci i valori di avanzamento al thread UI all’interno del callback, perché Notify viene eseguito sul thread che ha chiamato il costruttore 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;
        }
    }
}

In WPF, usa Dispatcher.Invoke o Dispatcher.BeginInvoke al posto di Control.BeginInvoke.

Come annullare un caricamento a lungo termine?

Imposta LoadOptions.CancellationToken su un token proveniente da un CancellationTokenSource, quindi chiama Cancel() su quella sorgente da un altro thread. Aspose.Tasks interrompe l’analisi e il costruttore Project genera un’eccezione, quindi avvolgilo in 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);
}

Conclusione

Aggiungere il progresso di caricamento a un’applicazione Aspose.Tasks for .NET è una piccola modifica con un grande effetto sulla reattività percepita. Implementa IProgressNotificationCallback, assegnalo a LoadOptions.ProjectLoadingCallback e leggi CurrentStepName, CurrentStepProgress e EstimatedTotalProgress all’interno di Notify. Aggiungi un CancellationToken quando i caricamenti possono durare a lungo abbastanza da far desiderare all’utente di interromperli.

Esplora la documentazione di Aspose.Tasks for .NET e il riferimento API per andare oltre, e scarica una licenza temporanea gratuita per valutare senza limiti.

FAQs

Devo avere una licenza a pagamento per utilizzare l’API di notifica di avanzamento?
No. IProgressNotificationCallback funziona in modalità di valutazione. Una licenza temporanea o a pagamento rimuove solo i limiti di valutazione su dimensione del file e output; non sblocca l’API di avanzamento.

La stessa callback funziona per i file XER così come per MPP?
Sì. LoadOptions.ProjectLoadingCallback è attualmente supportato per i formati MPP e XER. La stessa implementazione IProgressNotificationCallback gestisce entrambi.

Il callback di avanzamento è thread‑safe?
Notify viene invocato sul thread che esegue il caricamento, non su un thread in background. In un’app desktop, trasmetti i valori al thread UI con Control.Invoke o Dispatcher.Invoke prima di toccare una barra di avanzamento.

Qual è la differenza tra CurrentStepProgress e EstimatedTotalProgress?
CurrentStepProgress è la percentuale completata per la fase corrente del caricamento, ad esempio la lettura dei task o delle risorse. EstimatedTotalProgress è la percentuale stimata completata per l’intera operazione. Entrambi sono interi da 0 a 100.

Posso annullare un caricamento dall’interno del callback?
Non direttamente dall’interno di Notify. Invece, imposta LoadOptions.CancellationToken su un token proveniente da un CancellationTokenSource e chiama Cancel() su quella sorgente da un altro thread. Il costruttore Project si interrompe e lancia un’eccezione, quindi avvolgilo in try/catch.

L’aggiunta di un callback rallenta il caricamento?
L’overhead del callback è trascurabile perché Notify viene chiamato in un piccolo numero di checkpoint, non per record. Mantieni il metodo leggero, però, poiché qualsiasi lavoro tu faccia al suo interno viene eseguito sul thread di caricamento.

Leggi di più