-
March 12th, 2015, 11:19 AM
#1
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();
-
March 12th, 2015, 11:51 AM
#2
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!
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
March 12th, 2015, 11:58 AM
#3
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);
}
-
March 12th, 2015, 12:34 PM
#4
Re: New Process() freezes program until it finishes?
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.
-
March 12th, 2015, 03:45 PM
#5
Re: New Process() freezes program until it finishes?
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).
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|