BackgroundWorker-使用“子任务”报告进度

问题描述 投票:0回答:1

具有自定义控件LabelProgressBar的WinForms应用程序,它能够显示进度以及一些描述性文本和/或完成百分比。这是通过调用LabelProgressBar.statusInProgress(string message, int percentageCompletion)来完成的。

其一种用法如下:

private void import_begin(System.Object sender, System.ComponentModel.DoWorkEventArgs args)
{
    // first unpack the arguments
    System.Object[] arguments = (System.Object[])args.Argument;
    System.String filename = (System.String)arguments[0];
    System.String why = (System.String)arguments[1];

     // tasks:
     // 1. read excel file and apply changes to model
     // 2. gather changes and format them as XML
     // 3. send request to server
     // 4. commit/rollback changes

      // grab the worker thread so we can report percentage progress
      System.ComponentModel.BackgroundWorker worker = (System.ComponentModel.BackgroundWorker)sender;

     // now do the work
     #region Task1
     Controller.Excel excel = new Controller.Excel(filename);
     try
     {
          // the progress of this needs to be tracked
          overall_result = excel.import_all(out modified_nodes);
     }
     catch (InvalidDataExcetpion invDataEx)
     {
         // deal with it
     }
     #endregion
     worker.ReportProgress(25);

     // complete remaining tasks...
}

报告工作者进度的事件处理程序如下:

private void import_progress(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    Debug.WriteLine("Import percentage completion: " + e.ProgressPercentage);
    labelProgressBar1.statusInProgress("Import", e.ProgressPercentage);
}

简而言之,import_begin方法被分解为几个“任务”。这些被分解为“子任务”。以import_all方法为例:

public Command_Result import_all(out System.Collections.Generic.List<Model.Data_Node> nodes)
        {
            Command_Result overall_result = Command_Result.OK;
            Command_Result this_result;
            nodes = new System.Collections.Generic.List<Model.Data_Node>(excel.Workbook.Worksheets.Count);
            Model.Data_Node destination;

            // the intent is to report the progress of this particular subtask on the basis of how many worksheets have been processed in this for loop
            foreach (OfficeOpenXml.ExcelWorksheet worksheet in excel.Workbook.Worksheets)
            {
                this_result = import_sheet(worksheet.Name, out destination);
                nodes.Add(destination);
                if (this_result > overall_result)
                {
                    overall_result = this_result;
                }
            }

            return overall_result;
        }

目的是根据循环中处理了多少张纸来使此“子任务”报告进度。为此计算一个百分数很简单,但是我不清楚如何将其报告回import_begin方法。完成此“子任务”后,overall任务完成率(来自import_begin方法的POV)应为25%。其他任务也是如此。如何实现?

c# .net winforms progress-bar backgroundworker
1个回答
0
投票

import_begin确实不需要获取更新,它只需调用子任务,while也传递BackgroundWorker,因此子任务负责直接报告其进度

private void mainTask(object sender, DoWorkEventArgs e)
{
    var worker = (BackgroundWorker)sender;
    smallTask1(worker);
    smallTask2(worker);
    worker.ReportProgress(100);
}

void smallTask1(BackgroundWorker w)
{
    for (int i = 0; i < 20; i++)
    {
        Thread.Sleep(500);
        w.ReportProgress(i);
    }
}

void smallTask2(BackgroundWorker w)
{
    for (int i = 0; i < 5; i++)
    {
        Thread.Sleep(1000);
        w.ReportProgress(i*80/5+20);
    }
}

如果使用BackgroundWorker“污染”子任务是不可接受的,则创建一个委托来调用BackgroundWorker,这样您的子任务将改为调用该委托。

© www.soinside.com 2019 - 2024. All rights reserved.