Large Microsoft Project MPP และ Primavera XER สามารถใช้เวลาได้ตั้งแต่ไม่กี่วินาทีจนถึงหลายนาทีในการแยกข้อมูล ขณะนั้นแอปพลิเคชันแบบง่ายดูเหมือนจะค้าง: ไม่มีแถบความคืบหน้า, ไม่มีข้อความสถานะ, ไม่มีสิ่งใดที่ผู้ใช้สามารถทำได้ ผู้ที่โหลดตารางงานขนาดใหญ่ต้องการวิธีแสดงว่าการโหลดดำเนินไปไกลแค่ไหน และต้องการวิธีหยุดการโหลดที่ใช้เวลานานเกินไป.

คู่มือนี้ครอบคลุมทั้งสองอย่างด้วย Aspose.Tasks for .NET คุณจะสร้างคอลแบ็กการทำงานที่รายงานขั้นตอนปัจจุบันและเปอร์เซ็นต์ เชื่อมต่อมันกับการโหลด ทำให้ UI ของเดสก์ท็อปตอบสนองได้ขณะการแยกวิเคราะห์ทำงานบนเธรดพื้นหลัง และยกเลิกการโหลดที่เกินงบประมาณเวลา

Key Takeaways

  • IProgressNotificationCallback.Notify(ProgressNotificationArgs) เป็นเมธอดเดียวที่คุณต้องทำการ implement เพื่อรับความคืบหน้าในการโหลดจาก Aspose.Tasks for .NET.
  • ProgressNotificationArgs เปิดเผย CurrentStepName, CurrentStepProgress (0–100) และ EstimatedTotalProgress (0–100).
  • แนบ callback ด้วย LoadOptions.ProjectLoadingCallback; รองรับสำหรับรูปแบบไฟล์ MPP และ XER.
  • Notify ทำงานบนเธรดการโหลด ดังนั้นต้อง marshal ค่าต่าง ๆ ไปยัง UI thread ก่อนอัปเดตคอนโทรล.
  • ยกเลิกการโหลดที่ช้าโดยตั้งค่า LoadOptions.CancellationToken และเรียก Cancel() บน CancellationTokenSource ของมันจากเธรดอื่น.
  • API ความคืบหน้าทำงานในโหมดประเมินผล; ใบอนุญาตจะเพียงลบข้อจำกัดขนาดไฟล์และขนาดผลลัพธ์.

ใหม่กับไลบรารีนี้หรือไม่? หน้า Aspose.Tasks for .NET product page และ เอกสาร ครอบคลุมการตั้งค่าและการให้สิทธิ์อย่างเต็มรูปแบบ.

วิธีตรวจสอบความคืบหน้าการโหลดโครงการใน C#?

Implement IProgressNotificationCallback, ตั้งค่าให้กับ LoadOptions.ProjectLoadingCallback และโหลดไฟล์ผ่านคอนสตรัคเตอร์ Project ที่รับ LoadOptions. โค้ดทำงานขั้นต่ำประกอบด้วยสามส่วน: คลาส callback, อินสแตนซ์ LoadOptions และการเรียกโหลด.

  • Input: ไฟล์ MPP หรือ XER, ตัวอย่างเช่น BigProject.mpp
  • Output: การอัปเดตความคืบหน้าในระหว่างการแยกวิเคราะห์ — CurrentStepName, CurrentStepProgress, EstimatedTotalProgress
  • Library: Aspose.Tasks for .NET
  • Language: 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 และตั้งค่าโครงการ?

เพิ่มแพคเกจ NuGet ของ Aspose.Tasks ไปยังโครงการ .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, และอ่านข้อมูลเพิ่มเติมเกี่ยวกับไลบรารีได้ที่ หน้าผลิตภัณฑ์ Aspose.Tasks for .NET.

IProgressNotificationCallback API มีอะไรให้บริการ?

API มีเพียงอินเทอร์เฟซหนึ่งเมธอดหนึ่งและประเภทอาร์กิวเมนต์หนึ่งทั้งหมดอยู่ในเนมสเปซ 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. คุณสมบัติทั้งสามของมันเป็นแบบอ่านอย่างเดียว.

คุณจะทำคอลแบ็กการแจ้งเตือนความคืบหน้าอย่างไร?

สร้างคลาสที่ implements IProgressNotificationCallback และทำสิ่งที่เป็นประโยชน์กับ ProgressNotificationArgs ภายใน Notify ให้เมธอดทำงานเร็ว เพราะมันทำงานบนเธรดการโหลด

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 หลายครั้งที่รายงานจำนวนรวมเดียวกัน.

วิธีการโหลดโครงการพร้อมการติดตามความคืบหน้า?

ตั้ง ProjectLoadingCallback บนวัตถุ LoadOptions จากนั้นส่งผ่านไปยังคอนสตรัคเตอร์ 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 ภายในคอลแบ็ก เนื่องจาก Notify ทำงานบนเธรดที่เรียกตัวสร้าง 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;
        }
    }
}

ใน WPF ให้ใช้ Dispatcher.Invoke หรือ Dispatcher.BeginInvoke แทน Control.BeginInvoke

วิธีการยกเลิกการโหลดที่ใช้เวลานาน?

Set LoadOptions.CancellationToken ให้เป็นโทเค็นจาก CancellationTokenSource แล้วเรียก 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, และอ่านค่า CurrentStepName, CurrentStepProgress, และ EstimatedTotalProgress ภายใน Notify. เพิ่ม CancellationToken เมื่อการโหลดอาจใช้เวลานานพอที่ผู้ใช้อาจต้องการหยุดการทำงาน.

สำรวจ เอกสาร Aspose.Tasks for .NET และ อ้างอิง API เพื่อดำเนินการต่อไป และ ดาวน์โหลดใบอนุญาตชั่วคราวฟรี เพื่อประเมินโดยไม่มีข้อจำกัด.

คำถามที่พบบ่อย

ฉันต้องใช้ไลเซนส์แบบชำระเงินเพื่อใช้ API การแจ้งความคืบหน้าไหม?
ไม่. IProgressNotificationCallback ทำงานในโหมดประเมินผล. ไลเซนส์ชั่วคราวหรือแบบชำระเงินจะลบข้อจำกัดการประเมินผลเกี่ยวกับขนาดไฟล์และผลลัพธ์เท่านั้น; มันไม่ได้เปิดใช้งาน API การแจ้งความคืบหน้า.

คอลแบ็กเดียวกันทำงานกับไฟล์ XER เช่นเดียวกับ MPP หรือไม่? ใช่. LoadOptions.ProjectLoadingCallback ปัจจุบันรองรับรูปแบบ MPP และ XER. การทำงานของ IProgressNotificationCallback เดียวกันจัดการทั้งสอง.

การเรียกคืนความคืบหน้าปลอดภัยต่อเธรดหรือไม่?
Notify ถูกเรียกใช้บนเธรดที่ทำการโหลด ไม่ใช่เธรดพื้นหลัง ในแอปเดสก์ท็อป ให้ส่งค่าที่ได้ไปยังเธรด UI ด้วย Control.Invoke หรือ Dispatcher.Invoke ก่อนที่จะอัปเดตแถบความคืบหน้า

ความแตกต่างระหว่าง CurrentStepProgress และ EstimatedTotalProgress คืออะไร? CurrentStepProgress คือเปอร์เซ็นต์ที่เสร็จสมบูรณ์สำหรับขั้นตอนปัจจุบันของการโหลด เช่น การอ่านงานหรือการอ่านทรัพยากร. EstimatedTotalProgress คือเปอร์เซ็นต์ที่คาดว่าจะเสร็จสมบูรณ์สำหรับการดำเนินการทั้งหมด. ทั้งสองเป็นจำนวนเต็มตั้งแต่ 0 ถึง 100.

ฉันสามารถยกเลิกการโหลดจากภายใน callback ได้หรือไม่?
ไม่สามารถทำได้จากภายใน Notify โดยตรง แต่ให้ตั้งค่า LoadOptions.CancellationToken ให้เป็น token จาก CancellationTokenSource แล้วเรียก Cancel() บนแหล่งนั้นจากเธรดอื่น ตัวสร้าง Project จะหยุดและโยนข้อยกเว้น ดังนั้นให้ห่อไว้ใน try/catch.

การเพิ่ม callback ทำให้การโหลดช้าลงหรือไม่? ภาระของ callback นั้นเล็กน้อยเพราะ Notify ถูกเรียกที่จุดตรวจสอบจำนวนเล็กน้อย ไม่ได้ต่อแต่ละบันทึก อย่างไรก็ตาม ควรทำให้เมธอดมีน้ำหนักเบา เนื่องจากงานใด ๆ ที่คุณทำภายในจะทำงานบนเธรดการโหลด

อ่านต่อ