【问题标题】:How do I report to a ProgressBar when working with BackgroundWorker?使用 BackgroundWorker 时如何向 ProgressBar 报告?
【发布时间】:2014-06-20 10:40:26
【问题描述】:

我在form1中有一个progressBar1和BackgroundWorker,当我点击按钮创建avi文件时,我希望它根据avi文件创建进度报告给progressBar。

这是我创建 avi 文件的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AviFile;
using System.Drawing;
using System.IO;

namespace WindowsFormsApplication1
{
    class CreateAvi
    {
        public static void AviMovie(FileInfo[] FileNames)
        {
            Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName);
            AviManager aviManager =
                new AviManager(@"c:\temp\new.avi", false);
            VideoStream aviStream =
                aviManager.AddVideoStream(false, 25, bitmap);
            int count = 0;
            for (int n = 1; n < FileNames.Length; n++)
            {
                if (FileNames[n].Length > 0)
                {
                    bitmap =
                       (Bitmap)Bitmap.FromFile(FileNames[n].FullName);
                    aviStream.AddFrame(bitmap);
                    bitmap.Dispose();
                    count++;
                }
            }
            aviManager.Close();
        }
    }
}

在表格1中:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            CreateAvi.AviMovie(allfiles);
        }

进展:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

已完成:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }

这就是我在form1中所做的:

这是 CreateAvi 类中的方法,我对其进行了更改,因此它还将从 form1 中获取 backgroundworker(称为变量 bgw1):

public static void AviMovie(FileInfo[] FileNames,BackgroundWorker bgw1)
        {
            Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName);
            AviManager aviManager =
                new AviManager(@"c:\temp\new.avi", false);
            VideoStream aviStream =
                aviManager.AddVideoStream(false, 25, bitmap);
            int count = 0;
            for (int n = 0; n < FileNames.Length; n++)
            {
                if (FileNames[n].Length > 0)
                {
                    bitmap =
                       (Bitmap)Bitmap.FromFile(FileNames[n].FullName);
                    aviStream.AddFrame(bitmap);
                    bitmap.Dispose();
                    count++;
                    int pctDone = count * 100 / FileNames.Length;
                    bgw1.ReportProgress(pctDone);
                }
            }
            aviManager.Close();
        }

然后在form1中我改变了dowork事件,所以它会得到backgroundworker1:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            CreateAvi.AviMovie(allfiles,backgroundWorker1);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label9.Text = getallfiles[e.ProgressPercentage].FullName;
        }

所以progressBar 真正达到100% 到最后。但是,在 label19 中,我只看到文件 000101.jpg,在这个 idrectory 中有 167 个文件,最后一个是 000167.jpg

getallfiles 是 FileInfo[] 在 form1 构造函数中我做了:

var directory = new DirectoryInfo(mainDirectory);
getallfiles = directory.GetFiles("*.jpg");

我看到 getallfiles 包含 167 个文件。如何向标签报告正在处理的文件名?

【问题讨论】:

  • 您可以在 form1 上创建一个方法来更新 ProgressBar 的值(可能是自调用)。然后访问它或重构您的 CreateAviClass 以便它接受该方法的委托,您可以从您当时的非静态 AviMovie 方法调用该委托。 编辑: 或者只使用 DGibbs 建议的 Backgroundworker 的 ReportProgress 方法
  • 看看我的任务,请用我尝试将文件名报告给实验室的内容更新它
  • 在我没有显示我在 createavi 类中更改的内容之前再次编辑了我的问题我更改了方法,因此它将获得 backgroundworker1。
  • 更新标签将按照我在第一条评论中的建议进行。直接或通过委托访问的 Form1 上的自调用方法。

标签: c# .net winforms


【解决方案1】:

通过使用ReportProgress

private void DoWork()
{
    // Calculate percent done
    backgroundWorker.ReportProgress(percentageComplete);
}

这将触发backgroundWorker1_ProgressChanged 事件,您可以在其中安全地更新 UI。

【讨论】:

  • DGibbs 看看我的问题更新了我到目前为止所做的,但它不起作用。
  • 您尝试过的方式只有在完成AviMovie后才会报告您的进度
  • 嗯,一开始你不是在计算百分比值...你也需要从AviMovie 内部报告进度。您在操作完成后报告它。
【解决方案2】:

ReportProgress 需要从实际发生进度的方法中调用:

public static void AviMovie(FileInfo[] FileNames,BackgroundWorker bgw1)
{
   Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName);
   AviManager aviManager =new AviManager(@"c:\temp\new.avi", false);
   VideoStream aviStream =aviManager.AddVideoStream(false, 25, bitmap);
   int count = 0;
   for (int n = 0; n < FileNames.Length; n++)
   {
      if (FileNames[n].Length > 0)
      {
         bitmap =(Bitmap)Bitmap.FromFile(FileNames[n].FullName);
         aviStream.AddFrame(bitmap);
         bitmap.Dispose();
         count++;
         int pctDone = count * 100 / FileNames.Length;
         bgw1.ReportProgress(pctDone);
       }
    }
    aviManager.Close();
}

此外,您的循环需要从 0 开始——您将跳过 FileNames 中的第一个元素。

编辑:在后台工作人员的 ProgressChanged 事件中,您不能使用 e.ProgressPercentage 作为数组索引,您必须从百分比向后工作才能获得索引:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
   progressBar1.Value = e.ProgressPercentage;
   int fileIndex = e.ProgressPercentage * FileNames.Length/100;
   label9.Text = getallfiles[fileIndex].FullName; 
}

【讨论】:

  • 如何为标签分配当前正在处理的每个文件的名称?我尝试在 backgroundworker 进度事件中的 form1 中制作:label9.Text = allfiles[e.ProgressPercentage].FullName;但是当进度条达到 100% 到最后我只看到文件 000101.jpg 并且目录中的最后一个文件是 000167.jpg
  • C-Pound 看看我的任务,请用我尝试将文件名报告给标签的内容更新它。
  • 我还看到 CreateAvi 类中的 FileNames 也包含 167 个文件。那么为什么我在进度报告中只看到 101 个文件?
  • 在我没有显示我在 createavi 类中更改的内容之前再次编辑了我的问题我更改了方法,因此它将获得 backgroundworker1。
  • @user3756594:回答后更改问题会使答案无效。我建议提出一个问题,得到答案并接受它,然后如果您有其他问题,请单独提出(必要时参考原始问题)。
【解决方案3】:

您应该将 AviMovie() 的主体放入 bgw_DoWork(),并将这些行添加到主体的顶部:

FileInfo fileInfo = (FileInfo[])e.Argument;
int steps = fileInfo.Length;
BackgroundWorker bgw = (BackgroundWorker)sender;

在 for 循环的末尾添加这一行:

bgw.ReportProgress((int)(100 / steps) * n, null);

然后用这个启动worker:

bgw.RunWorkerAsync(FileNames); //FileNames is of course the array

当然还有其他方法可以做到,但这可能是我会做的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多