【问题标题】:foreach loop background worker issueforeach 循环后台工作者问题
【发布时间】:2013-12-18 11:13:14
【问题描述】:

我开发了一个使用 ffmpeg 工具进行视频音频合并的 wpf 程序。为此,我正在使用后台工作人员类。我将在此处包含我的代码。

    public VideoAudioMergeUserControl()
    {
        InitializeComponent();
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    }

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
       string progress= e.ProgressPercentage.ToString();
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        Process interactiveProcess = new Process();
        string processOutput = "";
        interactiveProcess.StartInfo.FileName = @"E:\ffmpeg.exe";
        interactiveProcess.StartInfo.UseShellExecute = false;
        interactiveProcess.StartInfo.CreateNoWindow = true;
        interactiveProcess.StartInfo.RedirectStandardInput = true;
        interactiveProcess.StartInfo.RedirectStandardError = true;

        ObservableCollection<VideoAudioCombined> videosAudios = (ObservableCollection<VideoAudioCombined>)e.Argument;
        foreach (VideoAudioCombined va in videosAudios)
        {

                string absoluteVideoPath = aviVideoPath + va.Video;
                string absoluteAudioPath = wavAudioPath + va.Audio;
                string relativeVideoPathSplit = va.Video.Substring(0, va.Video.Length - 4);
                string relativeAudioPathSplit = va.Audio.Substring(0, va.Audio.Length - 4);
                string outputavi = relativeVideoPathSplit + "_" + relativeAudioPathSplit + ".avi";
                string SelectedFileNameToSave = selectedFolder + outputavi;

                interactiveProcess.StartInfo.Arguments = "-i " + absoluteVideoPath + "  -i  " + absoluteAudioPath + "   -c:v copy -c:a aac -strict experimental " + SelectedFileNameToSave + " ";
                interactiveProcess.Start();
                interactiveProcess.EnableRaisingEvents = true;

                interactiveProcess.ErrorDataReceived += new DataReceivedEventHandler((process, outputEventArgs) => processOutput += outputEventArgs.Data);
                interactiveProcess.BeginErrorReadLine();
                bw.ReportProgress(100);

        }
    }



private void ButtonMerge_Click(object sender, RoutedEventArgs e)

        {
            System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
            folderDlg.ShowNewFolderButton = true;
            folderDlg.Description = Properties.Resources.MSG_Select_Folder_Merge_Audio_Video;

            // Show the FolderBrowserDialog.
            System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                selectedFolder = folderDlg.SelectedPath+"\\";

            }
            bw.RunWorkerAsync(VideoAudioCollection);         
        }

循环的第一次迭代不会产生任何问题。第二次迭代带来了以下问题 - “已在流上启动异步读取操作。”请帮忙。

【问题讨论】:

  • 启动后台工作者的代码部分在哪里?
  • 我包含了调用后台worker的代码。
  • 你的错误的原因是行'interactiveProcess.BeginErrorReadLine();'。您不必在 foreach 循环中使用单个进程调用该方法。在第一次迭代中,您启动了异步读取操作并继续,但在下一次迭代中,此操作已经开始。您必须查看逻辑才能启动流程。

标签: c# .net


【解决方案1】:

在启动后台工作者之前,请确保 IsBusy 为 false:

if (!bw.IsBusy) 
{
    bw.RunWorkerAsync(VideoAudioCollection);
}

如果 IsBusy 为真,则表示后台工作程序仍在工作,尚未完成其功能。在这种情况下,它会抛出异常。如果发生这种情况,您可以显示一个消息框,说
"仍在进行合并操作,请等待合并操作完成"。

你也可以尝试取消当前正在运行的操作调用

bw.CancelAsync();

【讨论】:

    【解决方案2】:

    你的错误的原因是这一行:interactiveProcess.BeginErrorReadLine();

    您不必在 foreach 循环中使用单个进程调用该方法。

    在第一次迭代中,您启动了异步读取操作并继续进行。事实上,在下一次迭代中,这个操作已经开始了。 根据文档:

    当异步读取操作开始时,事件处理程序被调用 每次关联的进程向其写入一行文本时 标准错误流。

    您必须查看启动流程的逻辑。我认为您应该为循环的每次迭代启动不同的过程,因为对于每次迭代,您都使用具有不同参数的相同过程,但使用相同的 StandardError 流。

    关于方法here的更多信息。

    【讨论】:

    • 嗨,我需要这个逻辑。在每次迭代中都有可能出现错误,因为文件名在每次迭代中都是不同的。所以我需要在每次迭代中保存错误(如果有的话)。请帮忙
    • @user1665130 作为建议,接受其他用户的回答,例如this one。如果您这样做,SO 用户会更乐意为您提供帮助。我刚刚说了错误在哪里以及如何解决问题:'你应该为循环的每次迭代启动一个不同的过程'。
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多