我如何报告到一个进度条与后台工作时

本文关键字:后台 工作 一个 何报告 报告 | 更新日期: 2023-09-27 18:09:27

我在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();
        }
    }
}
在form1:

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(称为变量bgw1)中获取backgroundworker:

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,在这个目录中有167个文件,最后一个是000167.jpg

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

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

我看到getallfiles包含167个文件。如何向标签报告进程的文件名

我如何报告到一个进度条与后台工作时

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

通过使用ReportProgress

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

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

你应该把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

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