对于每个循环后台辅助角色问题
本文关键字:角色 问题 后台 于每个 循环 | 更新日期: 2024-10-25 02:40:15
我开发了一个wpf程序,用于使用ffmpeg工具合并视频音频。我为此目的使用后台工人类。我将在此处包含我的代码。
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);
}
循环的第一次迭代不会产生任何问题。第二次迭代带来了以下问题 - "已在流上启动异步读取操作"。请帮忙。
在启动后台工作线程之前,请确保IsBusy
为 false:
if (!bw.IsBusy)
{
bw.RunWorkerAsync(VideoAudioCollection);
}
如果 IsBusy 为真,则表示后台工作者仍在工作并且尚未完成其功能。在这种情况下,它将引发异常。如果发生这种情况,您可以显示一个消息框,上面写着
"还有合并操作正在进行中,请等到合并操作完成"。
您也可以尝试取消当前正在运行的操作调用
bw.CancelAsync();
错误的原因是以下行: interactiveProcess.BeginErrorReadLine();
不必使用 foreach 循环中的单个进程调用该方法。
在第一次迭代中,您启动了异步读取操作,并继续执行。事实上,在下一次迭代中,此操作已经开始。根据文档:
异步读取操作启动时,将调用事件处理程序 每次关联的进程向其写入一行文本时 标准错误流。
您必须查看逻辑才能启动该过程。我认为您应该为循环的每次迭代启动一个不同的过程,因为对于每个迭代,您都使用相同的过程,具有不同的参数,但StandardError
流相同。
有关该方法的更多信息,请单击此处。