在 C# 中处理 StackOverflowException
StackOverflowException with Process in C#
我有一个在控制台应用程序中运行的进程。它永远运行。
几天后,应用程序崩溃并出现 WhosebugException。
应用程序的本质是我用 FFMpeg.exe 启动一个进程并创建视频流的截图。效果很好,但当时只用了几天。
我很确定这与 FFMpeg 或一些内部进程的处理有关。
这是代码
using ( Process ffmpegProcess = new Process() ) {
//arguments for running ffmpeg
ffmpegProcess.StartInfo.UseShellExecute = false;
ffmpegProcess.StartInfo.CreateNoWindow = true;
ffmpegProcess.StartInfo.RedirectStandardOutput = true;
//specific for our screenshots
ffmpegProcess.StartInfo.FileName = string.Concat( Environment.CurrentDirectory, Path.DirectorySeparatorChar, ffmpegProgramName );
try {
//todo: log this stopwatch somewhere perhaps
processWatch.Start();
//set arguments every time we want to create a new screen shot
ffmpegProcess.StartInfo.Arguments = string.Format( @"-y -i {0}{1} -threads 0 -ss 00:00:01.000 -f image2 -s 620x349 -vframes 1 ../../web/{2}.jpg", server, streamPath, slug );
ffmpegProcess.Start();
ffmpegProcess.WaitForExit( 500 );
Console.WriteLine( slug );
Console.WriteLine( processWatch.Elapsed );
processWatch.Reset();
runCount++;
cacheIndexer++;
//lets see how many spins we've had!
Console.WriteLine( string.Format( "SERVER CACHE INDEX : {0}", cacheIndexer ) );
Console.WriteLine( string.Format( "RUN : {0}", runCount ) );
Console.WriteLine( Environment.NewLine );
} catch ( Exception ex ) {
//Console.WriteLine( "Ex " + ex );
}
}
循环看起来像这样。
public void RecurseTask() {
/*
You can try one of these, but you will se CPU usage go crazy and perhaps concurrency errors due IO blocking
Parallel.ForEach( _videoStreamSlugs, ( e ) => _videoStreamScreenShots.GrabScreenShot( e ) );
foreach ( var slug in _videoStreamSlugs ) {
Task.Run( () => _videoStreamScreenShots.GrabScreenShot( slug ) );
}
*/
//we want to grab screen shots for every slug in out slug list!
foreach ( var slug in _videoStreamSlugs ) {
_videoStreamScreenShots.GrabScreenShot( slug );
}
//sleep for a little while
Thread.Sleep( _recurseInterval );
//A heavy clean up!
//We do this, trying to avoid a Whosebug excecption in the recursive method
//Please inspect this if problems arise
GC.Collect();
//lets grab over again
RecurseTask();
}
出于好奇,我添加了一个 GC.Collect,看看它是否有所作为。
我没有做 Windows 服务。
RecurseTask里面总是调用RecurseTask,很明显,long 运行的时候会抛出WhosebugException,你可以试试改成
public void RecurseTask() {
while(true)
{
/*
You can try one of these, but you will se CPU usage go crazy and perhaps concurrency errors due IO blocking
Parallel.ForEach( _videoStreamSlugs, ( e ) => _videoStreamScreenShots.GrabScreenShot( e ) );
foreach ( var slug in _videoStreamSlugs ) {
Task.Run( () => _videoStreamScreenShots.GrabScreenShot( slug ) );
}
*/
//we want to grab screen shots for every slug in out slug list!
foreach ( var slug in _videoStreamSlugs ) {
_videoStreamScreenShots.GrabScreenShot( slug );
}
//sleep for a little while
Thread.Sleep( _recurseInterval );
//A heavy clean up!
//We do this, trying to avoid a Whosebug excecption in the recursive method
//Please inspect this if problems arise
//GC.Collect(); Not needed
//lets grab over again
}
}
我有一个在控制台应用程序中运行的进程。它永远运行。
几天后,应用程序崩溃并出现 WhosebugException。
应用程序的本质是我用 FFMpeg.exe 启动一个进程并创建视频流的截图。效果很好,但当时只用了几天。
我很确定这与 FFMpeg 或一些内部进程的处理有关。
这是代码
using ( Process ffmpegProcess = new Process() ) {
//arguments for running ffmpeg
ffmpegProcess.StartInfo.UseShellExecute = false;
ffmpegProcess.StartInfo.CreateNoWindow = true;
ffmpegProcess.StartInfo.RedirectStandardOutput = true;
//specific for our screenshots
ffmpegProcess.StartInfo.FileName = string.Concat( Environment.CurrentDirectory, Path.DirectorySeparatorChar, ffmpegProgramName );
try {
//todo: log this stopwatch somewhere perhaps
processWatch.Start();
//set arguments every time we want to create a new screen shot
ffmpegProcess.StartInfo.Arguments = string.Format( @"-y -i {0}{1} -threads 0 -ss 00:00:01.000 -f image2 -s 620x349 -vframes 1 ../../web/{2}.jpg", server, streamPath, slug );
ffmpegProcess.Start();
ffmpegProcess.WaitForExit( 500 );
Console.WriteLine( slug );
Console.WriteLine( processWatch.Elapsed );
processWatch.Reset();
runCount++;
cacheIndexer++;
//lets see how many spins we've had!
Console.WriteLine( string.Format( "SERVER CACHE INDEX : {0}", cacheIndexer ) );
Console.WriteLine( string.Format( "RUN : {0}", runCount ) );
Console.WriteLine( Environment.NewLine );
} catch ( Exception ex ) {
//Console.WriteLine( "Ex " + ex );
}
}
循环看起来像这样。
public void RecurseTask() {
/*
You can try one of these, but you will se CPU usage go crazy and perhaps concurrency errors due IO blocking
Parallel.ForEach( _videoStreamSlugs, ( e ) => _videoStreamScreenShots.GrabScreenShot( e ) );
foreach ( var slug in _videoStreamSlugs ) {
Task.Run( () => _videoStreamScreenShots.GrabScreenShot( slug ) );
}
*/
//we want to grab screen shots for every slug in out slug list!
foreach ( var slug in _videoStreamSlugs ) {
_videoStreamScreenShots.GrabScreenShot( slug );
}
//sleep for a little while
Thread.Sleep( _recurseInterval );
//A heavy clean up!
//We do this, trying to avoid a Whosebug excecption in the recursive method
//Please inspect this if problems arise
GC.Collect();
//lets grab over again
RecurseTask();
}
出于好奇,我添加了一个 GC.Collect,看看它是否有所作为。
我没有做 Windows 服务。
RecurseTask里面总是调用RecurseTask,很明显,long 运行的时候会抛出WhosebugException,你可以试试改成
public void RecurseTask() {
while(true)
{
/*
You can try one of these, but you will se CPU usage go crazy and perhaps concurrency errors due IO blocking
Parallel.ForEach( _videoStreamSlugs, ( e ) => _videoStreamScreenShots.GrabScreenShot( e ) );
foreach ( var slug in _videoStreamSlugs ) {
Task.Run( () => _videoStreamScreenShots.GrabScreenShot( slug ) );
}
*/
//we want to grab screen shots for every slug in out slug list!
foreach ( var slug in _videoStreamSlugs ) {
_videoStreamScreenShots.GrabScreenShot( slug );
}
//sleep for a little while
Thread.Sleep( _recurseInterval );
//A heavy clean up!
//We do this, trying to avoid a Whosebug excecption in the recursive method
//Please inspect this if problems arise
//GC.Collect(); Not needed
//lets grab over again
}
}