为什么在向背景工作者报告时,它永远不会进入progresschanged事件?

时间:2016-06-07 23:35:29

标签: c# .net winforms backgroundworker

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace ConvertVideo
{
    public partial class Form1 : Form
    {
        string InputFile = @"C:\temp\video\new.avi";
        string OutputFile = @"C:\temp\video\new.wmv";
        string cmd;
        string exepath = @"E:\myffmpegstatic\ffmpeg-20151217-git-9d1fb9e-win64-static\bin\ffmpeg.exe";
        FileInfo fi;

        public Form1()
        {
            InitializeComponent();

            backgroundWorker1.WorkerReportsProgress = true;
            fi = new FileInfo(InputFile);
            label2.Text = InputFile;
            cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
            backgroundWorker1.RunWorkerAsync();
        }

        private void ConvertNow(string cmd)
        {
            try
            {
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo.FileName = exepath;
                proc.StartInfo.Arguments = cmd;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.RedirectStandardOutput = true;

                // use this event
                proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); // use this for synchronization

                proc.Start();

                // and start asynchronous read
                proc.BeginOutputReadLine();

                // wait until it's finished in your background worker thread
                proc.WaitForExit();
            }
            catch(Exception err)
            {
                string myerr = err.ToString();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            ConvertNow(cmd);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            textBox1.Text = e.ProgressPercentage.ToString();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}

我想要的是向progresschanged事件报告进度和数据,并更新textbox1和progressBar(我在设计器中有progressBar1)。

在progressBar中,我想将百分比转换进度报告为100%

不确定如何制作此报告,但我确定它没有进入progresschanged事件。使用断点我看到它正在上线:

backgroundWorker1.ReportProgress(0, e.Data);

在backgroundworker属性的deisgner中,WorkerReportsProgress设置为true。

1 个答案:

答案 0 :(得分:1)

你在这里说过:

<script>



    $.ajax({
        type: "POST",

        url: "http://rpmdev.company.com/WebServices/wsUserMaint.asmx?op=ResetPassword",
        headers: {
            'Access-Control-Allow-Origin': 'http://rpmdev.company.com',
        },
        data: "{}",
        //contentType: "application/json; charset=utf-8",
        dataType: "jsonp",
        success: function (msg) {
            var data = msg.d;
        },
        error: function (msg) {
            alert(msg.responseText);
        }
    });


</script>

因此,您在事件的 proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); 参数中通过ffmpeg发送每行输出的string内容,并且您在进度百分比中发送UserState。但是在0处理程序中,您只检查ProgressChanged参数 - 您只向其发送零的参数。

ProgressPercentage

所以...当然,除了零之外,你不会在文本框中看到任何内容。

如果您在表单上放置一个列表框并尝试,例如:

 textBox1.Text = e.ProgressPercentage.ToString();

您应该会发现列表框中填充了 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.UserState != null) { listBox1.Items.Add(e.UserState.ToString()); } } 的控制台输出。如果你想从中提取一个百分比,你必须解析输出并根据帧数或时间指数估计你的距离。

有关从ffmpeg获取进展的其他方法,请参阅:

PHP中的答案,但它应该给你一些更好的想法。

有关演示您的方法合理的完整工作示例,则使用ffmpeg(每个人都应该拥有)并要求ipconfig具有Form1和{{{ 1}}事件已连接,以及添加到表单的列表框。

ProgressChanged