我如何在后台计算DoWork事件,以便ReportProgress(百分比)将达到100%,progressBar1将到

本文关键字:百分比 将到 progressBar1 100% 以便 后台 计算 事件 DoWork ReportProgress | 更新日期: 2023-09-27 18:19:09

这就是我在DoWork事件和ProgressChanged事件中所做的:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    double total = streamlength;
    int counter = 0;
    int percentage = 0;
    BackgroundWorker bgw = (BackgroundWorker)sender;
    int i = 0;
    for (double x = 0; x < streamlength; x += dt)
    {
        streamDouble[0] = x;
        SaveFramesFromVideo(strVideoFile, streamDouble, sf + i.ToString("D6") + ".bmp");
        i++;
        counter += 1;
        percentage = counter * 100 / (int)total;
        bgw.ReportProgress(percentage);
    }
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

我看到progressBar1的进度从左到右显示为绿色,但在中间,我在ProgressChanged事件中得到异常:

ArgumentOutOfRangeException:值"133"对"Value"无效。"值"应该在"最小值"answers"最大值"之间。参数名称:值

错误行:progressBar1.Value = e.ProgressPercentage; in The progressChanged event.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExtractFrames.Properties;
using ExtractFrames;
using JockerSoft.Media;
using JockerSoft;
using Interop.qedit;
using Interop;
using System.Runtime.InteropServices;
using System.IO;
namespace ExtractFrames
{
    public partial class Form1 : Form
    {
        double dt;
        FolderBrowserDialog fb;
        OpenFileDialog openFileDialog1;
        private bool _connect = false;
        private bool _rightButton;
        List<LinePoint> _points = null;
        private float _circleWidth = 10;
        DirectoryInfo dir1;
        FileInfo[] fi;
        double streamlength;
        MediaDet mdd;
        double x;
        string sf;
        double[] streamDouble ;
        string strVideoFile;
        public Form1()
        {
            InitializeComponent();
            fb = new FolderBrowserDialog();
            openFileDialog1 = new OpenFileDialog();
            mdd = new MediaDet();
            streamDouble = new double[1];
            sf = @"d:'Frames'";
            dir1 = new DirectoryInfo(sf);
            fi = dir1.GetFiles("*.bmp");
            if (fi.Length == 0)
            {
                trackBar1.Enabled = false;
            }
            else
            {
                trackBar1.Minimum = 0;
                trackBar1.Maximum = fi.Length - 1;
                trackBar1.Value = 0;//fi.Length - 1;
                Bitmap newImage;
                newImage = new Bitmap(fi[0].FullName);
                pictureBox1.Image = newImage;
            }
        }
        private  void getFrameRate()
        {
            // Get framerate
            MediaDet md = new MediaDet();
            md.Filename = strVideoFile;
            //md.CurrentStream = 0;                     // choose the video stream
            x = md.FrameRate;
            double i = md.StreamLength;
        }
        public static void SaveFramesFromVideo(string videoFile, double[] positions, string outputBitmapFiles)
        {
            if (videoFile == null)
                throw new ArgumentNullException("videoFile");
            double streamLength;
            IMediaDet mediaDet = null;
            try
            {
                _AMMediaType mediaType;
                if (openVideoStream(videoFile, out mediaDet, out mediaType))
                {
                    streamLength = mediaDet.StreamLength;
                    Size target = getVideoSize(mediaType);
                    int iteration = 0;
                    foreach (double position in positions)
                    {
                        iteration++;
                        string outputBitmapFile = string.Format(outputBitmapFiles, iteration);                        
                        mediaDet.WriteBitmapBits(position, target.Width, target.Height, outputBitmapFile);
                    }
                }
            }
            catch (COMException)
            {
                throw new InvalidVideoFileException();
            }
            finally
            {
                if (mediaDet != null)
                    Marshal.ReleaseComObject(mediaDet);
            }
            return;
        }

        private static Size getVideoSize(_AMMediaType mediaType)
        {
            WinStructs.VIDEOINFOHEADER videoInfo = (WinStructs.VIDEOINFOHEADER)Marshal.PtrToStructure(mediaType.pbFormat, typeof(WinStructs.VIDEOINFOHEADER));
            return new Size(videoInfo.bmiHeader.biWidth, videoInfo.bmiHeader.biHeight);
        }
        private static Size scaleToFit(Size target, Size original)
        {
            if (target.Height * original.Width > target.Width * original.Height)
                target.Height = target.Width * original.Height / original.Width;
            else
                target.Width = target.Height * original.Width / original.Height;
            return target;
        }
        private static Size scaleToFitSmart(Size target, Size original)
        {
            target = scaleToFit(target, original);
            if (target.Width > original.Width || target.Height > original.Height)
                return original;
            return target;
        }
        private static bool openVideoStream(string videoFile, out IMediaDet mediaDet, out _AMMediaType aMMediaType)
        {
            mediaDet = new MediaDet();
            //loads file
            mediaDet.Filename = videoFile;
            //gets # of streams
            int streamsNumber = mediaDet.OutputStreams;
            //finds a video stream
            for (int i = 0; i < streamsNumber; i++)
            {
                mediaDet.CurrentStream = i;
                _AMMediaType mediaType = mediaDet.StreamMediaType;
                if (mediaType.majortype == JockerSoft.Media.MayorTypes.MEDIATYPE_Video)
                {
                    //video stream found
                    aMMediaType = mediaType;
                    return true;
                }
            }
            //no video stream found
            Marshal.ReleaseComObject(mediaDet);
            mediaDet = null;
            aMMediaType = new _AMMediaType();
            return false;
        }

        private bool LoadPictureAt(int nIndex, object c)
        {
            bool bRet = false;
            if (nIndex >= 0 && nIndex < fi.Length)
            {
                if (c.Equals(trackBar1))
                    pictureBox1.Load(fi[nIndex].FullName);
                bRet = true;
            }
            return bRet;
        }
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            LoadPictureAt(trackBar1.Value, sender);
        }
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (_points != null)
            {
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                using (SolidBrush myBrush = new SolidBrush(Color.Red))
                {
                    for (int i = 0; i < _points.Count; i++)
                    {
                        try
                        {
                            Point pt = _points[i].Point;
                            e.Graphics.FillEllipse(myBrush, new RectangleF(pt.X - _circleWidth / 2F, pt.Y - _circleWidth / 2F, _circleWidth, _circleWidth));
                            if (i > 0)
                            {
                                if (_points[i].Connected)
                                    e.Graphics.DrawLine(Pens.Blue, _points[i - 1].Point, _points[i].Point);
                            }
                        }
                        catch ( Exception err)
                        {
                            textBox1.Text = err.ToString();
                        }
                    }
                }
            }
        }
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (_points == null)
                    _points = new List<LinePoint>();
                _points.Add(new LinePoint() { Point = new Point(e.X, e.Y), Connected = _connect });
                pictureBox1.Invalidate();
            }
            if (e.Button == MouseButtons.Right)
            {
                _connect = !_connect;
                _rightButton = true;
            }
        }
        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            _points.Clear();
            if (_rightButton && _points != null)
                _points.Clear();
            pictureBox1.Invalidate();
        }
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            _rightButton = false;
        }
        public class LinePoint
        {
            public Point Point { get; set; }
            public bool Connected { get; set; }
        }
        private void loadVideoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "Select a video file";
            openFileDialog1.InitialDirectory = "c:''";
            openFileDialog1.FileName = null;
            openFileDialog1.Filter = "Video Files|*.wmv;*.3gp;*.avi";
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.RestoreDirectory = true;
            DialogResult result1 = openFileDialog1.ShowDialog();
            string file1 = openFileDialog1.FileName;
            if (result1 == DialogResult.OK)
            {
                strVideoFile = file1;
                mdd.Filename = strVideoFile;
                streamlength = mdd.StreamLength;
                dt = (double)1 / mdd.FrameRate;//(double)20; //mdd.FrameRate;
                backgroundWorker1.RunWorkerAsync();
            }
            if (result1 == DialogResult.Cancel)
            {
                if (file1 == "")
                {
                }
            }
        }
        private void changeExtractedFramesDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            fb.Description = "Directory To Extract Frames";
            DialogResult result = fb.ShowDialog();
            string file1 = fb.SelectedPath;
        }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            double total = streamlength;
            int counter = 0;
            int percentage = 0;
            BackgroundWorker bgw = (BackgroundWorker)sender;
            int i = 1;
            for (double x = 0; x < total; x += dt)
            {
                streamDouble[0] = x;
                SaveFramesFromVideo(strVideoFile, streamDouble, sf + i.ToString("D6") + ".bmp");
                i++;
                counter += 1;
                //percentage = counter * 100 / (int)total;
                percentage = (int)((x / streamlength) * 100.0); 
                bgw.ReportProgress(percentage);
            }
            bgw.ReportProgress(100);
        }
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //progressBar1.Value = e.ProgressPercentage;
            progressBar1.Value = Math.Max(0, Math.Min(100, e.ProgressPercentage)); 
        }
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            fi = dir1.GetFiles("*.bmp");
            if (fi.Length == 0)
            {
                trackBar1.Enabled = false;
            }
            else
            {
                trackBar1.Enabled = true;
                trackBar1.Minimum = 0;
                trackBar1.Maximum = fi.Length - 1;
                trackBar1.Value = 0;//fi.Length - 1;
                Bitmap newImage;
                newImage = new Bitmap(fi[0].FullName);
                pictureBox1.Image = newImage;
            }
        }
    }
}

我如何在后台计算DoWork事件,以便ReportProgress(百分比)将达到100%,progressBar1将到

我看不到变量streamlengthdt的声明。backgroundworker(顾名思义)在后台工作。所以你的程序是并行工作的,UI是反应性的,当后台工作人员工作时,流长度的值可能会改变。在这种情况下,for循环运行到另一端streamlength,然后计算百分比(您将streamlength存储在total中并使用它进行计算)。第一种方法是这样更改方法backgroundWorker1_DoWork:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{
    double total = streamlength;
    int counter = 0;
    int percentage = 0;
    BackgroundWorker bgw = (BackgroundWorker)sender;
    int i = 0;
    for (double x = 0; x < total; x += dt)
    {
        streamDouble[0] = x;
        SaveFramesFromVideo(strVideoFile, streamDouble, sf + i.ToString("D6") + ".bmp");
        i++;
        counter += 1;
        percentage = counter * 100 / (int)total;
        bgw.ReportProgress(percentage);
    }
} 

现在应该可以了,但是我强烈建议你重新考虑一下这个程序。

尝试进行以下更改。首先,将百分比的计算更改为:

percentage = (int)((x / streamlength) * 100.0);

使用x而不是计数器。我要做这个改变,因为这是你实际用来循环的。

接下来,为了确保不会因为舍入错误而出现问题,可以将进度条的值赋值更改为:

progressBar1.Value = Math.Max(0, Math.Min(100, e.ProgressPercentage));

这将确保分配的值始终在0到100之间。