Arquivos grandes do Microsoft Project MPP e Primavera XER podem levar de alguns segundos a vários minutos para serem analisados. Enquanto isso ocorre, uma aplicação ingênua parece congelada: sem barra de progresso, sem texto de status, nada que o usuário possa agir. Quem carrega cronogramas grandes precisa de uma maneira de mostrar o quão avançado está o carregamento e de uma forma de interromper um que esteja demorando demais.

Este guia cobre ambos com Aspose.Tasks for .NET. Você criará um callback de progresso que relata a fase atual e a porcentagem, conectá‑lo ao carregamento, manterá a UI de desktop responsiva enquanto a análise é executada em uma thread em segundo plano e cancelará um carregamento que exceda o orçamento de tempo.

Principais Conclusões

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) é o único método que você implementa para receber o progresso de carregamento do Aspose.Tasks for .NET.
  • ProgressNotificationArgs expõe CurrentStepName, CurrentStepProgress (0–100) e EstimatedTotalProgress (0–100).
  • Anexe o callback usando LoadOptions.ProjectLoadingCallback; ele é suportado para os formatos MPP e XER.
  • Notify é executado na thread de carregamento, portanto encaminhe os valores para a thread de UI antes de atualizar um controle.
  • Cancele um carregamento lento definindo LoadOptions.CancellationToken e chamando Cancel() em seu CancellationTokenSource a partir de outra thread.
  • A API de progresso funciona no modo de avaliação; uma licença apenas remove limites de tamanho de arquivo e de saída.

Novo na biblioteca? A página do produto Aspose.Tasks for .NET e a documentação cobrem a configuração e a licença em detalhes.

Como monitorar o progresso de carregamento do projeto em C#?

Implemente IProgressNotificationCallback, defina‑o em LoadOptions.ProjectLoadingCallback e carregue o arquivo através do construtor Project que aceita LoadOptions. O código mínimo funcional consiste em três partes: uma classe de callback, uma instância de LoadOptions e a chamada de carregamento.

  • Entrada: um arquivo MPP ou XER, por exemplo BigProject.mpp
  • Saída: atualizações de progresso durante a análise — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • Biblioteca: Aspose.Tasks for .NET
  • Linguagem: 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);
    }
}

À medida que o arquivo é analisado, Notify é executado várias vezes e o console mostra a fase e as porcentagens. Após o retorno do construtor, o objeto Project está totalmente carregado e utilizável.

Por que o monitoramento de progresso de carregamento importa para arquivos grandes?

Ele substitui uma pausa que parece não responsiva por um feedback visível, que é a diferença entre um aplicativo que parece quebrado e um que parece ocupado. Quanto maior o arquivo, mais longa será a análise, e mais um carregamento cego custa em qualidade percebida.

Usos concretos para os valores de progresso:

  • Controle uma barra de progresso determinada usando EstimatedTotalProgress em vez de exibir um spinner indefinido.
  • Registre as transições de CurrentStepName para descobrir qual fase domina o tempo de carregamento ao analisar um arquivo lento.
  • Mantenha a UI responsiva carregando em uma thread em segundo plano e enviando o progresso para a thread da UI.
  • Exiba o progresso por arquivo em uma ferramenta em lote que converte ou migra vários projetos em sequência.

Como Instalar o Aspose.Tasks e Configurar o Projeto?

Adicione o pacote NuGet Aspose.Tasks a um projeto .NET 6 ou posterior.

dotnet add package Aspose.Tasks

Ou, a partir do Console do Gerenciador de Pacotes do Visual Studio:

Install-Package Aspose.Tasks

O callback de progresso funciona sem licença. Se precisar carregar arquivos acima do limite de tamanho de avaliação ou processar sem restrições de avaliação, defina uma licença uma vez na inicialização:

using Aspose.Tasks;

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

Você pode solicitar uma licença temporária gratuita na página de licença temporária da Aspose, e ler mais sobre a biblioteca na página do produto Aspose.Tasks for .NET.

O que a API IProgressNotificationCallback fornece?

A API consiste em uma interface, um método e um tipo de argumento, todos no namespace Aspose.Tasks.

MembroTipoDescrição
IProgressNotificationCallback.Notify(ProgressNotificationArgs)voidChamado durante operações de projeto de longa duração para relatar o progresso.
ProgressNotificationArgs.CurrentStepNamestring (get)Nome da fase atual da operação.
ProgressNotificationArgs.CurrentStepProgressint (get)Porcentagem estimada concluída para a fase atual, 0–100.
ProgressNotificationArgs.EstimatedTotalProgressint (get)Porcentagem estimada concluída para toda a operação, 0–100.
LoadOptions.ProjectLoadingCallbackIProgressNotificationCallback (get/set)O callback invocado durante o carregamento. Compatível com MPP e XER.
LoadOptions.CancellationTokenSystem.Threading.CancellationToken (get/set)Token usado para cancelar um carregamento em andamento.

ProgressNotificationArgs é selado e deriva de EventArgs. Todas as três propriedades são somente leitura.

Como implementar um callback de notificação de progresso?

Crie uma classe que implemente IProgressNotificationCallback e faça algo útil com o ProgressNotificationArgs dentro de Notify. Mantenha o método rápido, pois ele é executado na thread de carregamento.

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

A verificação em lastTotal evita inundar o console com linhas duplicadas quando várias chamadas Notify relatam o mesmo total.

Como Carregar um Projeto com Rastreamento de Progresso?

Defina ProjectLoadingCallback em um objeto LoadOptions e, em seguida, passe‑o para o construtor Project. O carregamento é executado de forma síncrona; quando o construtor retorna, a análise está concluída.

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

Tentando isso nos seus próprios horários? Baixe uma licença temporária gratuita para executar cargas sem o limite de avaliação no tamanho do arquivo.

Como manter a UI responsiva durante o carregamento?

Carregue em uma thread em segundo plano e encaminhe os valores de progresso para a thread da UI dentro do callback, porque Notify é executado na thread que chamou o construtor 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;
        }
    }
}

No WPF, use Dispatcher.Invoke ou Dispatcher.BeginInvoke no lugar de Control.BeginInvoke.

Como cancelar um carregamento de longa duração?

Defina LoadOptions.CancellationToken para um token de um CancellationTokenSource, então chame Cancel() nessa fonte a partir de outra thread. Aspose.Tasks interrompe a análise e o construtor Project lança uma exceção, portanto envolva‑o em 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);
}

Conclusão

Adicionar progresso de carregamento a uma aplicação Aspose.Tasks for .NET é uma pequena mudança com um grande efeito na responsividade percebida. Implemente IProgressNotificationCallback, atribua‑o a LoadOptions.ProjectLoadingCallback e leia CurrentStepName, CurrentStepProgress e EstimatedTotalProgress dentro de Notify. Adicione um CancellationToken quando os carregamentos podem durar tempo suficiente para que o usuário deseje interrompê‑los.

Explore a documentação do Aspose.Tasks for .NET e a referência da API para ir mais longe, e baixe uma licença temporária gratuita para avaliar sem limites.

FAQs

Preciso de uma licença paga para usar a API de notificação de progresso?
Não. IProgressNotificationCallback funciona no modo de avaliação. Uma licença temporária ou paga apenas remove os limites de avaliação de tamanho de arquivo e saída; ela não desbloqueia a API de progresso.

O mesmo callback funciona para arquivos XER assim como para MPP?
Sim. LoadOptions.ProjectLoadingCallback é atualmente suportado para os formatos MPP e XER. A mesma implementação IProgressNotificationCallback lida com ambos.

É thread‑safe o callback de progresso?
Notify é invocado na thread que executa o carregamento, não em uma thread em segundo plano. Em um aplicativo desktop, encaminhe os valores para a thread da UI usando Control.Invoke ou Dispatcher.Invoke antes de manipular uma barra de progresso.

Qual é a diferença entre CurrentStepProgress e EstimatedTotalProgress? CurrentStepProgress é a porcentagem concluída para a fase atual da carga, como leitura de tarefas ou leitura de recursos. EstimatedTotalProgress é a porcentagem estimada concluída para toda a operação. Ambos são inteiros de 0 a 100.

Posso cancelar um carregamento de dentro da callback?
Não a partir de dentro do Notify diretamente. Em vez disso, defina LoadOptions.CancellationToken para um token de um CancellationTokenSource e chame Cancel() nessa fonte a partir de outra thread. O construtor Project então para e lança uma exceção, portanto envolva‑o em try/catch.

Adicionar um callback desacelera o carregamento? A sobrecarga do callback é insignificante porque Notify é chamado em um pequeno número de pontos de verificação, não por registro. Mantenha o método leve, porém, já que qualquer trabalho que você faça dentro dele é executado na thread de carregamento.

Leia Mais