New Process() freezes program until it finishes?
Hello everyone, I am calling up FFMPEG and passing arguments to it to transcode video files. The program works great with my existing code, however when it is working on any larger files, I noticed that my program freezes while FFMPEG is running. As it runs, I read the standard error output, which give me status and progress updates about twice a second.
I know the problem is in Synchronous vs Asynchronous processes, but the sample code I have seen for Async Processes only appears to check for the output once, whereas I need to read it continuously as it comes available. I have a "kill-switch" which I want to check periodically to be able to abort the process, but once I call FFMPEG, it doesn't get read until after it has finished... There has to be a way to run asynchronous and still continuously monitor the output, right?
Code:
Process proc = new Process();
proc.StartInfo.FileName = "C:\\FFMPEG\\bin\\ffmpeg.exe";
proc.StartInfo.Arguments = "-i " + sourceFile + "-c:v dnxhd -b:v 185M -r 29.97 -s 1920x1080 -pix_fmt yuv422p10le -flags +ildct -c:a pcm_s24le -ar 48k dnxhdoutput.mov";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.EnableRaisingEvents = true;
if (!proc.Start())
{
Console.WriteLine("Error starting");
return;
}
StreamReader reader = proc.StandardError;
string line;
string fileName = Path.GetFileName(Item.Text); //get the filename without path...
int fileNum = Item.Index + 1;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
labelStatus.Text = fileNum + " of " + fileList1.CheckedIndices.Count + ": " + fileName + " - " + line;
labelStatus.Update();
//Check for Kill Switch!
//if (checkKill.Checked == true)
//{
// proc.Close();
//}
}
proc.Close();
Re: New Process() freezes program until it finishes?
One way (which I use a lot) is to wrap the synchronous code (that is working) into a clean class structure, and then invoke the method on that class asynchronously (e.g. so that it runs on a separate thread). Now the communication between the processes is synchronous, but the communication by the threads is async!
Re: New Process() freezes program until it finishes?
I will have to try that. Sounds like something I would do :)
Here is another approach I took, but still causing the freezing...
Code:
void StartProcess(string arguments)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "C:\\FFMPEG\\bin\\ffmpeg.exe",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
}
};
process.OutputDataReceived += (sender, args) => Display(args.Data);
process.ErrorDataReceived += (sender, args) => Display(args.Data);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit(); //you need this in order to flush the output buffer
}
void Display(string output)
{
Console.WriteLine(output);
}
Re: New Process() freezes program until it finishes?
Quote:
Originally Posted by
iBkickinit
I will have to try that. Sounds like something I would do :)
Here is another approach I took, but still causing the freezing...
Code:
void StartProcess(string arguments)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "C:\\FFMPEG\\bin\\ffmpeg.exe",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
}
};
process.OutputDataReceived += (sender, args) => Display(args.Data);
process.ErrorDataReceived += (sender, args) => Display(args.Data);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit(); //you need this in order to flush the output buffer
}
void Display(string output)
{
Console.WriteLine(output);
}
The following line causes the launched program to be synchronous (and freezes your UI).
Code:
process.WaitForExit(); //you need this in order to flush the output buffer
As CPU mentioned, you need to start that process from another (non-UI) thread.
Re: New Process() freezes program until it finishes?
Quote:
Originally Posted by
Arjay
As CPU mentioned, you need to start that process from another (non-UI) thread.
I never said "need to"... The "WaitForExit" could be removed and logic written to use the "Exited" event [ https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx ].
However, I rarely use that approach as implementing proper cleanup of all of the associated async structures can be quite difficult (and therefore error prone).