Große Microsoft Project MPP und Primavera XER Dateien können beim Parsen von wenigen Sekunden bis zu mehreren Minuten dauern. Währenddessen wirkt eine naive Anwendung eingefroren: keine Fortschrittsanzeige, kein Status‑Text, nichts, worauf der Benutzer reagieren kann. Jeder, der große Zeitpläne lädt, benötigt eine Möglichkeit, den Fortschritt des Ladevorgangs anzuzeigen, und eine Möglichkeit, einen zu lange laufenden Vorgang zu stoppen.
Dieser Leitfaden behandelt beides mit Aspose.Tasks for .NET. Sie erstellen einen Fortschritts‑Callback, der die aktuelle Phase und einen Prozentsatz meldet, binden ihn in den Ladevorgang ein, halten die Desktop‑UI reaktionsfähig, während das Parsen in einem Hintergrund‑Thread läuft, und brechen einen Ladevorgang ab, der das Zeitbudget überschreitet.
Wichtige Erkenntnisse
IProgressNotificationCallback.Notify(ProgressNotificationArgs)ist die einzige Methode, die Sie implementieren, um den Ladevorgang‑Fortschritt von Aspose.Tasks for .NET zu erhalten.ProgressNotificationArgsstelltCurrentStepName,CurrentStepProgress(0–100) undEstimatedTotalProgress(0–100) bereit.- Binden Sie den Callback mit
LoadOptions.ProjectLoadingCallback; er wird für die Formate MPP und XER unterstützt. Notifywird im Ladevorgang‑Thread ausgeführt, daher sollten Sie die Werte vor der Aktualisierung einer Steuerung in den UI‑Thread marshallen.- Brechen Sie einen langsamen Ladevorgang ab, indem Sie
LoadOptions.CancellationTokensetzen und von einem anderen ThreadCancel()auf dessenCancellationTokenSourceaufrufen. - Die Fortschritts‑API funktioniert im Evaluierungsmodus; eine Lizenz entfernt lediglich Beschränkungen für Dateigröße und Ausgabe.
Neu in der Bibliothek? Die Aspose.Tasks for .NET Produktseite und die Dokumentation decken die Einrichtung und Lizenzierung vollständig ab.
Wie überwacht man den Projektladefortschritt in C#?
Implementieren Sie IProgressNotificationCallback, setzen Sie es auf LoadOptions.ProjectLoadingCallback und laden Sie die Datei über den Project‑Konstruktor, der LoadOptions akzeptiert. Der minimale funktionierende Code besteht aus drei Teilen: einer Callback‑Klasse, einer LoadOptions‑Instanz und dem Ladevorgang.
- Eingabe: eine MPP- oder XER-Datei, zum Beispiel
BigProject.mpp - Ausgabe: Fortschrittsaktualisierungen während des Parsens —
CurrentStepName,CurrentStepProgress,EstimatedTotalProgress - Bibliothek: Aspose.Tasks for .NET
- Sprache: 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);
}
}
Wenn die Datei geparst wird, wird Notify mehrmals ausgeführt und die Konsole zeigt die Phase und Prozentsätze an. Nachdem der Konstruktor zurückkehrt, ist das Project‑Objekt vollständig geladen und einsatzbereit.
Warum ist die Überwachung des Ladefortschritts bei großen Dateien wichtig?
Es ersetzt eine nicht reagierende Pause durch sichtbares Feedback, was den Unterschied zwischen einer Anwendung, die kaputt wirkt, und einer, die beschäftigt aussieht, ausmacht. Je größer die Datei, desto länger die Analyse, und je mehr ein blindes Laden Ihnen an wahrgenommener Qualität kostet.
Konkrete Verwendungszwecke für die Fortschrittswerte:
- Steuern Sie eine bestimmte Fortschrittsanzeige über
EstimatedTotalProgressanstatt einen unbestimmten Spinner anzuzeigen. - Protokollieren Sie
CurrentStepName‑Übergänge, um herauszufinden, welche Phase die Ladezeit dominiert, wenn Sie eine langsame Datei profilieren. - Halten Sie die UI responsiv, indem Sie im Hintergrund‑Thread laden und den Fortschritt an den UI‑Thread übermitteln.
- Zeigen Sie den Fortschritt pro Datei in einem Batch‑Tool an, das viele Projekte nacheinander konvertiert oder migriert.
Wie installieren Sie Aspose.Tasks und richten das Projekt ein?
Fügen Sie das Aspose.Tasks NuGet-Paket zu einem .NET 6‑ oder höheren Projekt hinzu.
dotnet add package Aspose.Tasks
Oder, über die Visual Studio-Paket-Manager-Konsole:
Install-Package Aspose.Tasks
Der Fortschritts‑Callback funktioniert ohne Lizenz. Wenn Sie Dateien über dem Evaluationsgrößenlimit laden oder ohne Evaluationsbeschränkungen verarbeiten müssen, setzen Sie einmalig beim Start eine Lizenz:
using Aspose.Tasks;
var license = new License();
license.SetLicense("Aspose.Tasks.lic");
Sie können eine kostenlose temporäre Lizenz von der Aspose temporäre Lizenzseite anfordern und mehr über die Bibliothek auf der Aspose.Tasks for .NET Produktseite lesen.
Was bietet die IProgressNotificationCallback-API?
Die API besteht aus einer Schnittstelle, einer Methode und einem Argumenttyp, alles im Aspose.Tasks Namensraum.
| Mitglied | Typ | Beschreibung |
|---|---|---|
IProgressNotificationCallback.Notify(ProgressNotificationArgs) | void | Wird während langwieriger Projektoperationen aufgerufen, um den Fortschritt zu melden. |
ProgressNotificationArgs.CurrentStepName | string (get) | Name der aktuellen Phase der Operation. |
ProgressNotificationArgs.CurrentStepProgress | int (get) | Geschätzter Prozentsatz der Fertigstellung für die aktuelle Phase, 0–100. |
ProgressNotificationArgs.EstimatedTotalProgress | int (get) | Geschätzter Prozentsatz der Fertigstellung für die gesamte Operation, 0–100. |
LoadOptions.ProjectLoadingCallback | IProgressNotificationCallback (get/set) | Der Callback, der während des Ladens aufgerufen wird. Unterstützt für MPP und XER. |
LoadOptions.CancellationToken | System.Threading.CancellationToken (get/set) | Token, das zum Abbrechen eines laufenden Ladevorgangs verwendet wird. |
ProgressNotificationArgs ist versiegelt und leitet sich von EventArgs ab. Alle drei seiner Eigenschaften sind schreibgeschützt.
Wie implementieren Sie einen Fortschrittsbenachrichtigungs-Callback?
Erstellen Sie eine Klasse, die IProgressNotificationCallback implementiert, und machen Sie etwas Nützliches mit den ProgressNotificationArgs innerhalb von Notify. Halten Sie die Methode schnell, da sie im Lade‑Thread ausgeführt wird.
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);
}
}
Der Guard für lastTotal verhindert, dass die Konsole mit doppelten Zeilen überflutet wird, wenn mehrere Notify‑Aufrufe denselben Gesamtwert melden.
Wie laden Sie ein Projekt mit Fortschrittsverfolgung?
Setzen Sie ProjectLoadingCallback auf ein LoadOptions‑Objekt und übergeben Sie es anschließend dem Project‑Konstruktor. Der Ladevorgang wird synchron ausgeführt; wenn der Konstruktor zurückkehrt, ist das Parsen abgeschlossen.
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;
}
}
Möchten Sie das nach Ihrem eigenen Zeitplan ausprobieren? Laden Sie eine kostenlose temporäre Lizenz herunter um Vorgänge auszuführen, ohne das Bewertungslimit für die Dateigröße.
Wie halten Sie eine UI beim Laden reaktionsfähig?
Laden Sie in einem Hintergrund‑Thread und marshallen Sie die Fortschrittswerte innerhalb des Callbacks zum UI‑Thread, weil Notify in dem Thread ausgeführt wird, der den Project‑Konstruktor aufgerufen hat.
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 verwenden Sie Dispatcher.Invoke oder Dispatcher.BeginInvoke anstelle von Control.BeginInvoke.
Wie brechen Sie einen langlaufenden Ladevorgang ab?
Setzen Sie LoadOptions.CancellationToken auf ein Token aus einer CancellationTokenSource und rufen Sie dann Cancel() auf dieser Quelle aus einem anderen Thread auf. Aspose.Tasks stoppt das Parsen und der Project-Konstruktor wirft eine Ausnahme, also wickeln Sie ihn in try/catch ein.
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);
}
Fazit
Das Hinzufügen eines Ladefortschritts zu einer Aspose.Tasks for .NET‑Anwendung ist eine kleine Änderung mit großer Wirkung auf die wahrgenommene Reaktionsfähigkeit. Implementieren Sie IProgressNotificationCallback, weisen Sie ihn LoadOptions.ProjectLoadingCallback zu und lesen Sie CurrentStepName, CurrentStepProgress und EstimatedTotalProgress innerhalb von Notify. Fügen Sie ein CancellationToken hinzu, wenn Ladevorgänge lange genug dauern können, dass ein Benutzer sie stoppen möchte.
Entdecken Sie die Aspose.Tasks for .NET Dokumentation und die API-Referenz, um weiterzugehen, und laden Sie eine kostenlose temporäre Lizenz herunter, um ohne Einschränkungen zu evaluieren.
FAQs
Benötige ich eine kostenpflichtige Lizenz, um die Fortschrittsbenachrichtigungs‑API zu verwenden?
Nein. IProgressNotificationCallback funktioniert im Evaluierungsmodus. Eine temporäre oder kostenpflichtige Lizenz entfernt lediglich die Evaluierungsbeschränkungen für Dateigröße und Ausgabe; sie schaltet die Fortschritts‑API nicht frei.
Funktioniert derselbe Callback sowohl für XER-Dateien als auch für MPP?
Ja. LoadOptions.ProjectLoadingCallback wird derzeit für die MPP- und XER-Formate unterstützt. Die gleiche IProgressNotificationCallback‑Implementierung verarbeitet beide.
Ist der Fortschritts-Callback thread‑sicher?Notify wird im Thread aufgerufen, der den Ladevorgang ausführt, nicht in einem Hintergrundthread. In einer Desktop‑App sollten die Werte mit Control.Invoke oder Dispatcher.Invoke an den UI‑Thread marshalled werden, bevor ein Fortschrittsbalken aktualisiert wird.
Was ist der Unterschied zwischen CurrentStepProgress und EstimatedTotalProgress?CurrentStepProgress ist der prozentuale Fortschritt für die aktuelle Phase des Ladevorgangs, z. B. beim Lesen von Aufgaben oder Ressourcen. EstimatedTotalProgress ist der geschätzte prozentuale Fortschritt für den gesamten Vorgang. Beide sind Ganzzahlen von 0 bis 100.
Kann ich einen Ladevorgang aus dem Callback heraus abbrechen?
Nicht direkt aus Notify. Stattdessen setzen Sie LoadOptions.CancellationToken auf ein Token von einer CancellationTokenSource und rufen Cancel() auf dieser Quelle aus einem anderen Thread auf. Der Project‑Konstruktor stoppt dann und wirft eine Ausnahme, also wickeln Sie ihn in try/catch ein.
Verlangsamt das Hinzufügen eines Callbacks das Laden?
Der Overhead des Callbacks ist vernachlässigbar, weil Notify nur an einer kleinen Anzahl von Checkpoints aufgerufen wird, nicht pro Datensatz. Halten Sie die Methode jedoch leichtgewichtig, da jede Arbeit, die Sie darin ausführen, im Ladethread läuft.
