【问题标题】:C# - Using BackgroundWorker.ReportProgress to update ProgressBar with custom Maximum valueC# - 使用 BackgroundWorker.ReportProgress 以自定义最大值更新 ProgressBar
【发布时间】:2016-03-13 09:58:51
【问题描述】:

我在这个主题上搜索了几天,但没有发现任何相关的内容。请记住,我仍在学习如何在 C# 中使用 BackgroundWorker 和多线程。

我在使用 ReportProgress 方法时遇到问题。这是我正在做的一个小例子。

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
  if (!backgroundWorker1.CancellationPending)
  {
    // bunch of code for handling a multiple-page PDF file using Ghostscript.NET
    for (var pageNumber = 1; pageNumber <= pageCount; pageNumber++)
    {
      if (!backgroundWorker1.CancellationPending)
      {
        // get file path and file name, convert page to image file
        // after converting page to image file do:
        backgroundWorker1.ReportProgress(pageNumber); // Here is the problem
      }
      else
        e.Cancel = true;
      ...
    }
  }
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
  progressBar1.Value = e.ProgressPercentage;
}

我遇到的问题是我想为用户提供一个进度条,该进度条将在文件转换时更新进度,以便 UI 不会无响应。进度条的最大值属性设置为 100,但显然每个 PDF 文件不会是 100 页 - 上面的代码仅将 progressPercent 值报告为每个单独的页面 - 所以如果 PDF 不是,进度条只会部分填充100 页。

所以这是我的问题:如何使用 ReportProgress 方法适当地更新进度条?通过在报告进度之前设置最大值(通过在 DoWork 中使用 Invoke),我让程序更早地工作。但是,我最近了解到您不应该使用 BackgroundWorker 的 DoWork 事件更新 UI(仍在研究中)。所以如果 ReportProgress 只取一个整数值,我如何用正确的百分比更新进度条?显然,我不能使用 ReportProgress 报告“16.67%”。

提前感谢您的时间和建议。

【问题讨论】:

    标签: c# .net backgroundworker


    【解决方案1】:

    如果您仔细查看可用于 ReportProgress 方法的签名,您会注意到除了已完成工作的百分比之外,还有一个重载允许传递您自己的对象。
    第二个参数可以是引用类型的实例,但也可以是一个简单的整数值,例如当前 PDF 的页数。

    作为第二个参数传递给 ReportProgress 的值可以在事件处理程序中检索为 ProgressChangedEventArgs.UserState 属性的值

    因此,您可以在 DoWork 方法中开始循环之前使用它传递 pageCount 变量以及 ProgressPercentage 值的常规值 -1

    private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
      if (!backgroundWorker1.CancellationPending)
      {
    
        int pageCount = CalculatePageCount();
        backgroundWorker1.ReportProgress(-1, pageCount); 
        for (var pageNumber = 1; pageNumber <= pageCount; pageNumber++)
           ..... 
    
      }
    }
    
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
      // First call, the percentage is negative to signal that UserState
      // contains the number of pages we loop on....
      if(e.ProgressPercentage == -1)
         progressBar1.Maximum = Convert.ToInt32(e.UserState);
      else
         progressBar1.Value = e.ProgressPercentage;
    }
    

    【讨论】:

    • 我认为这正是我所需要的,谢谢。我想没有看过 UserState 属性,因为我认为我不能这样使用它。
    【解决方案2】:

    ...或者只是将值报告为(int)(pageNumber * 100 / totalPages)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      相关资源
      最近更新 更多