大規模な Microsoft Project の MPP および Primavera の XER ファイルは、解析に数秒から数分かかることがあります。その間、単純なアプリケーションはフリーズしたように見えます:プログレスバーもステータステキストもなく、ユーザーが操作できるものがありません。大きなスケジュールを読み込むすべての人は、ロードの進行状況を示す方法と、実行時間が長すぎる場合に停止できる方法が必要です。

このガイドでは、Aspose.Tasks for .NET を使用した両方の方法をカバーします。現在のフェーズとパーセンテージを報告するプログレスコールバックを作成し、ロードに組み込み、解析がバックグラウンドスレッドで実行されている間にデスクトップ UI の応答性を保ち、時間予算を超えるロードをキャンセルします。

主なポイント

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) は、Aspose.Tasks for .NET からロード進捗を受け取るために実装する唯一のメソッドです。
  • ProgressNotificationArgsCurrentStepNameCurrentStepProgress(0–100)、および EstimatedTotalProgress(0–100)を公開します。
  • コールバックは LoadOptions.ProjectLoadingCallback で添付します。これは MPP および XER フォーマットでサポートされています。
  • Notify はロードスレッド上で実行されるため、コントロールを更新する前に値を UI スレッドへマーシャリングしてください。
  • 別スレッドから LoadOptions.CancellationToken を設定し、その CancellationTokenSourceCancel() を呼び出すことで、遅いロードをキャンセルできます。
  • 進捗 API は評価モードで動作します。ライセンスはファイルサイズと出力の制限のみを解除します。

ライブラリは初めてですか? Aspose.Tasks for .NET 製品ページドキュメント では、セットアップとライセンスについて完全にカバーしています。

C# でプロジェクトのロード進行状況を監視する方法は?

IProgressNotificationCallback を実装し、LoadOptions.ProjectLoadingCallback に設定し、LoadOptions を受け取る Project コンストラクタを使用してファイルをロードします。最小限の動作コードは 3 つの部分で構成されます: コールバック クラス、LoadOptions インスタンス、そしてロード呼び出しです。

  • 入力: MPP または XER ファイル、例として BigProject.mpp
  • 出力: パース中の進捗更新 — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • ライブラリ: Aspose.Tasks for .NET
  • 言語: 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);
    }
}

ファイルが解析されると、Notify が複数回実行され、コンソールにフェーズとパーセンテージが表示されます。コンストラクタが戻った後、Project オブジェクトは完全にロードされ、使用可能になります。

大きなファイルでロード進捗モニタリングが重要な理由は何ですか?

それは、応答がないように見える一時停止を可視的なフィードバックに置き換えます。これが、壊れているように見えるアプリケーションと、忙しそうに見えるアプリケーションの違いです。ファイルが大きくなるほど解析に時間がかかり、盲目的なロードが知覚品質に与えるコストは大きくなります。

進捗値の具体的な使用例:

  • EstimatedTotalProgress から決定的なプログレスバーを駆動し、無限スピナーを表示しないようにします。
  • CurrentStepName の遷移をログに記録し、スローファイルをプロファイルするときにどのフェーズがロード時間を支配しているかを特定します。
  • バックグラウンドスレッドでロードし、プログレスを UI スレッドに投稿することで、UI の応答性を保ちます。
  • 複数のプロジェクトを順次変換または移行するバッチツールで、ファイルごとの進捗を表示します。

Aspose.Tasks のインストール方法とプロジェクトの設定方法は?

Aspose.Tasks NuGet パッケージを .NET 6 以降のプロジェクトに追加します。

dotnet add package Aspose.Tasks

または、Visual Studio パッケージ マネージャ コンソールから:

Install-Package Aspose.Tasks

プログレスコールバックはライセンスなしでも機能します。評価サイズ制限を超えるファイルを読み込む必要がある場合や、評価制限なしで処理する場合は、起動時に一度ライセンスを設定してください。

using Aspose.Tasks;

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

無料の一時ライセンスは Aspose temporary license page からリクエストでき、ライブラリの詳細は Aspose.Tasks for .NET product page でご覧いただけます。

IProgressNotificationCallback API は何を提供しますか?

API は 1 つのインターフェイス、1 つのメソッド、そして 1 つの引数型で構成されており、すべて Aspose.Tasks 名前空間にあります。

MemberTypeDescription
IProgressNotificationCallback.Notify(ProgressNotificationArgs)void長時間実行されるプロジェクト操作中に進捗を報告するために呼び出されます。
ProgressNotificationArgs.CurrentStepNamestring (get)操作の現在のフェーズの名前。
ProgressNotificationArgs.CurrentStepProgressint (get)現在のフェーズの完了予測パーセンテージ(0〜100)。
ProgressNotificationArgs.EstimatedTotalProgressint (get)全体の操作の完了予測パーセンテージ(0〜100)。
LoadOptions.ProjectLoadingCallbackIProgressNotificationCallback (get/set)ロード中に呼び出されるコールバック。MPP と XER に対応しています。
LoadOptions.CancellationTokenSystem.Threading.CancellationToken (get/set)進行中のロードをキャンセルするために使用されるトークン。

ProgressNotificationArgs は sealed で、EventArgs から派生しています。その3つのプロパティはすべて読み取り専用です。

プログレス通知コールバックを実装するにはどうすればよいですか?

IProgressNotificationCallback を実装するクラスを作成し、Notify 内の ProgressNotificationArgs を使って有用な処理を行います。ロードスレッド上で実行されるため、メソッドは高速に保ってください。

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

lastTotal のガードは、複数の Notify 呼び出しが同じ合計を報告する際に、コンソールが重複した行で埋め尽くされるのを防ぎます。

プロジェクトをプログレス追跡付きでロードするにはどうすればよいですか?

LoadOptions オブジェクトに ProjectLoadingCallback を設定し、Project コンストラクタに渡します。ロードは同期的に実行され、コンストラクタが返ると解析が完了します。

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

自分のスケジュールでこれを試してみますか? 無料の一時ライセンスをダウンロード ファイルサイズの評価制限なしでロードを実行できます。

ロード中に UI を応答性のある状態に保つにはどうすればよいですか?

バックグラウンドスレッドでロードし、コールバック内で進捗値を UI スレッドにマーシャルします。NotifyProject コンストラクタを呼び出したスレッド上で実行されるためです。

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

WPF では、Control.BeginInvoke の代わりに Dispatcher.Invoke または Dispatcher.BeginInvoke を使用します。

長時間実行されるロードをキャンセルするには?

LoadOptions.CancellationTokenCancellationTokenSource から取得したトークンに設定し、別スレッドからそのソースの Cancel() を呼び出します。Aspose.Tasks は解析を停止し、Project コンストラクタが例外をスローするので、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);
}

結論

Aspose.Tasks for .NET アプリケーションにロード進捗を追加することは、知覚される応答性に大きな効果をもたらす小さな変更です。IProgressNotificationCallback を実装し、LoadOptions.ProjectLoadingCallback に割り当て、Notify 内で CurrentStepNameCurrentStepProgressEstimatedTotalProgress を読み取ります。ロードが長時間実行され、ユーザーが停止したくなる可能性がある場合は、CancellationToken を追加します。

Aspose.Tasks for .NET documentationAPI リファレンス を参照し、さらに詳しく知り、無料の一時ライセンスをダウンロード して制限なく評価してください。

FAQs

プログレス通知 API を使用するのに有料ライセンスは必要ですか? いいえ。IProgressNotificationCallback は評価モードで動作します。一時的または有料のライセンスは、ファイルサイズや出力に対する評価制限を解除するだけで、プログレス API のロックを解除するわけではありません。

XER ファイルでも MPP と同様に同じコールバックは機能しますか?
はい。 LoadOptions.ProjectLoadingCallback は現在 MPP および XER フォーマットでサポートされています。同じ IProgressNotificationCallback 実装が両方を処理します。

進行状況コールバックはスレッドセーフですか? Notify はロードを実行しているスレッド上で呼び出され、バックグラウンドスレッドではありません。デスクトップ アプリでは、プログレス バーに触れる前に Control.Invoke または Dispatcher.Invoke を使用して値を UI スレッドにマーシャルしてください。

CurrentStepProgress と EstimatedTotalProgress の違いは何ですか? CurrentStepProgress は、タスクの読み取りやリソースの読み取りなど、ロードの現在のフェーズの完了率を示すパーセンテージです。EstimatedTotalProgress は、全体の操作の推定完了率を示すパーセンテージです。どちらも 0 から 100 の整数です。

コールバック内からロードをキャンセルできますか?
Notify 内から直接はできません。代わりに、LoadOptions.CancellationTokenCancellationTokenSource から取得したトークンを設定し、別スレッドからそのソースの Cancel() を呼び出します。Project コンストラクタは停止して例外をスローするので、try/catch で囲んでください。

コールバックを追加するとロードが遅くなりますか?
コールバックのオーバーヘッドは、Notify がレコードごとではなく、少数のチェックポイントで呼び出されるため、無視できる程度です。ただし、メソッドは軽量に保ってください。内部で行う作業はすべてロードスレッド上で実行されるためです。

続きを読む