Los archivos grandes de Microsoft Project MPP y Primavera XER pueden tardar desde unos pocos segundos hasta varios minutos en analizarse. Mientras eso ocurre, una aplicación ingenua parece congelada: sin barra de progreso, sin texto de estado, nada en lo que el usuario pueda actuar. Cualquier persona que cargue horarios extensos necesita una forma de mostrar cuánto avanza la carga y una manera de detenerla si se ejecuta demasiado tiempo.

Esta guía cubre ambos con Aspose.Tasks for .NET. Creará una devolución de llamada de progreso que informe la fase actual y un porcentaje, la integrará en la carga, mantendrá la interfaz de usuario de escritorio receptiva mientras el análisis se ejecuta en un subproceso en segundo plano, y cancelará una carga que exceda el presupuesto de tiempo.

Puntos clave

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) es el único método que implementas para recibir el progreso de carga de Aspose.Tasks for .NET.
  • ProgressNotificationArgs expone CurrentStepName, CurrentStepProgress (0–100) y EstimatedTotalProgress (0–100).
  • Adjunta la devolución de llamada con LoadOptions.ProjectLoadingCallback; es compatible con los formatos MPP y XER.
  • Notify se ejecuta en el hilo de carga, por lo que debes trasladar los valores al hilo de UI antes de actualizar un control.
  • Cancela una carga lenta estableciendo LoadOptions.CancellationToken y llamando a Cancel() en su CancellationTokenSource desde otro hilo.
  • La API de progreso funciona en modo de evaluación; una licencia solo elimina los límites de tamaño de archivo y de salida.

¿Nuevo en la biblioteca? La página del producto Aspose.Tasks for .NET y la documentación cubren la configuración y la licencia en detalle.

¿Cómo monitorear el progreso de carga del proyecto en C#?

Implemente IProgressNotificationCallback, configúrelo en LoadOptions.ProjectLoadingCallback y cargue el archivo mediante el constructor Project que acepta LoadOptions. El código mínimo funcional consta de tres partes: una clase de devolución de llamada, una instancia de LoadOptions y la llamada de carga.

  • Entrada: un archivo MPP o XER, por ejemplo BigProject.mpp
  • Salida: actualizaciones de progreso durante el análisis — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • Biblioteca: Aspose.Tasks for .NET
  • Lenguaje: 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);
    }
}

Al analizar el archivo, Notify se ejecuta varias veces y la consola muestra la fase y los porcentajes. Después de que el constructor devuelve, el objeto Project está completamente cargado y listo para usar.

¿Por qué es importante el monitoreo del progreso de carga para archivos grandes?

Reemplaza una pausa que parece no responder con una retroalimentación visible, lo que marca la diferencia entre una aplicación que parece rota y una que parece ocupada. Cuanto mayor sea el archivo, más largo será el análisis, y más le cuesta una carga ciega en términos de calidad percibida.

Usos concretos para los valores de progreso:

  • Conduce una barra de progreso determinada desde EstimatedTotalProgress en lugar de mostrar un spinner indefinido.
  • Registra las transiciones de CurrentStepName para encontrar qué fase domina el tiempo de carga al perfilar un archivo lento.
  • Mantén la UI receptiva cargando en un hilo de fondo y publicando el progreso en el hilo de UI.
  • Muestra el progreso por archivo en una herramienta por lotes que convierte o migra muchos proyectos en secuencia.

¿Cómo instalar Aspose.Tasks y configurar el proyecto?

Agregue el paquete NuGet Aspose.Tasks a un proyecto .NET 6 o posterior.

dotnet add package Aspose.Tasks

O, desde la consola del Administrador de paquetes de Visual Studio:

Install-Package Aspose.Tasks

La devolución de llamada de progreso funciona sin una licencia. Si necesita cargar archivos que superen el límite de tamaño de evaluación o procesar sin restricciones de evaluación, establezca una licencia una vez al iniciar:

using Aspose.Tasks;

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

Puede solicitar una licencia temporal gratuita en la página de licencia temporal de Aspose, y leer más sobre la biblioteca en la página del producto Aspose.Tasks for .NET.

¿Qué proporciona la API IProgressNotificationCallback?

La API es una interfaz, un método y un tipo de argumento, todo en el espacio de nombres Aspose.Tasks.

MiembroTipoDescripción
IProgressNotificationCallback.Notify(ProgressNotificationArgs)voidSe llama durante operaciones de proyecto de larga duración para informar del progreso.
ProgressNotificationArgs.CurrentStepNamestring (get)Nombre de la fase actual de la operación.
ProgressNotificationArgs.CurrentStepProgressint (get)Porcentaje estimado completado de la fase actual, 0–100.
ProgressNotificationArgs.EstimatedTotalProgressint (get)Porcentaje estimado completado de toda la operación, 0–100.
LoadOptions.ProjectLoadingCallbackIProgressNotificationCallback (get/set)La devolución de llamada invocada durante la carga. Compatible con MPP y XER.
LoadOptions.CancellationTokenSystem.Threading.CancellationToken (get/set)Token utilizado para cancelar una carga en curso.

ProgressNotificationArgs está sellada y deriva de EventArgs. Las tres propiedades son de solo lectura.

¿Cómo implementas una devolución de llamada de notificación de progreso?

Cree una clase que implemente IProgressNotificationCallback y haga algo útil con ProgressNotificationArgs dentro de Notify. Mantenga el método rápido, porque se ejecuta en el hilo de carga.

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

La protección en lastTotal evita inundar la consola con líneas duplicadas cuando varias llamadas a Notify informan el mismo total.

¿Cómo cargar un proyecto con seguimiento de progreso?

Establezca ProjectLoadingCallback en un objeto LoadOptions, luego páselo al constructor Project. La carga se ejecuta de forma sincrónica; cuando el constructor devuelve, el análisis está completo.

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

¿Probándolo en tus propios horarios? Descarga una licencia temporal gratuita para ejecutar cargas sin el límite de evaluación en el tamaño del archivo.

¿Cómo mantener una UI receptiva mientras se carga?

Cargue en un subproceso en segundo plano y transmita los valores de progreso al subproceso de la interfaz de usuario dentro de la devolución de llamada, porque Notify se ejecuta en el subproceso que llamó al constructor 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;
        }
    }
}

En WPF, use Dispatcher.Invoke o Dispatcher.BeginInvoke en lugar de Control.BeginInvoke.

¿Cómo cancelar una carga de larga duración?

Establezca LoadOptions.CancellationToken a un token de un CancellationTokenSource, luego llame a Cancel() en esa fuente desde otro hilo. Aspose.Tasks detiene el análisis y el constructor Project lanza una excepción, por lo que debe envolverlo en 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);
}

Conclusión

Agregar progreso de carga a una aplicación Aspose.Tasks for .NET es un cambio pequeño con un gran efecto en la capacidad de respuesta percibida. Implemente IProgressNotificationCallback, asígnelo a LoadOptions.ProjectLoadingCallback y lea CurrentStepName, CurrentStepProgress y EstimatedTotalProgress dentro de Notify. Añada un CancellationToken cuando las cargas pueden ejecutarse lo suficientemente tiempo como para que el usuario desee detenerlas.

Explore la documentación de Aspose.Tasks for .NET y la referencia de la API para profundizar, y descargue una licencia temporal gratuita para evaluar sin límites.

Preguntas frecuentes

¿Necesito una licencia de pago para usar la API de notificación de progreso?
No. IProgressNotificationCallback funciona en modo de evaluación. Una licencia temporal o de pago solo elimina los límites de evaluación en el tamaño del archivo y la salida; no desbloquea la API de progreso.

¿La misma devolución de llamada funciona tanto para archivos XER como para MPP?
Sí. LoadOptions.ProjectLoadingCallback es compatible actualmente con los formatos MPP y XER. La misma implementación de IProgressNotificationCallback maneja ambos.

¿Es el callback de progreso seguro para subprocesos? Notify se invoca en el hilo que ejecuta la carga, no en un hilo en segundo plano. En una aplicación de escritorio, envíe los valores al hilo de UI con Control.Invoke o Dispatcher.Invoke antes de manipular una barra de progreso.

¿Cuál es la diferencia entre CurrentStepProgress y EstimatedTotalProgress? CurrentStepProgress es el porcentaje completado para la fase actual de la carga, como la lectura de tareas o la lectura de recursos. EstimatedTotalProgress es el porcentaje estimado completado para toda la operación. Ambos son enteros de 0 a 100.

¿Puedo cancelar una carga desde dentro del callback? No desde dentro de Notify directamente. En su lugar, establezca LoadOptions.CancellationToken a un token de un CancellationTokenSource y llame a Cancel() en esa fuente desde otro hilo. El constructor Project entonces se detiene y lanza una excepción, así que envuélvalo en try/catch.

¿Agregar una devolución de llamada ralentiza la carga? La sobrecarga de la devolución de llamada es insignificante porque Notify se llama en un pequeño número de puntos de control, no por registro. Sin embargo, mantenga el método liviano, ya que cualquier trabajo que realice dentro de él se ejecuta en el hilo de carga.

Leer más