2010-12-20 10 views
3

私は数日間問題を解決しようとしています。私はマルチスレッドの初心者です。私の目標は、ffmpeg.exeを使用して複数のビデオエンコードタスクを同時に実行し、サーバーのすべての機能を使用することです。競合のない外部exe(ffmpeg)でのタスク並列ライブラリ(C#.NET 4.0)の使用

私はこのようになりますどの ffmpeg.exeプロセスを起動し、スレッド(または唯一のffmpegの内部スレッド(FLVのエンコードには使用できません)を使用)せずに動作するC#のラッパーを持って

using (Process process = new Process()) 
{ 
    process.StartInfo.FileName = encoderPath + "ffmpeg.exe"; 

    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.StartInfo.RedirectStandardError = true; 
    process.StartInfo.CreateNoWindow = false; 

    string arguments = "-y -i " + filenameInput + " -f " + 
     GetVideoFormatName(format) + " -vcodec " + GetVideoCodecName(codec); 

    // (most argument setup has been omitted for brevity) 
    arguments += " " + filenameOutput + " "; 

    process.StartInfo.Arguments = arguments; 
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    process.Start(); 

    bool succes = LireSortie(process); 
    process.WaitForExit(); 
    process.Close(); 
    return succes; 
} 

以下のコードラッパーを呼び出します。各Encodeメソッドの2番目のパラメータは、内部ffmpegスレッドに使用するスレッドの数です。私はそれを無効にすると、動作しません。

var fm = new FFMpegWrapper(); 

fm.FilenameInput = "test.mp4"; 
//VideoInfo videoinfo = fm.GetVideoInfo(); 
Task[] tasks = { 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto200p("test200p.mp4", 4); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.EncodetoFlash200p("test200p.flv"); })), 
    // ... (calls to other Encode methods ommitted) ... 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto404p("test404p.mp4", 4); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.EncodetoFlash404p("test404p.flv"); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto720p("test720p.mp4", 4); })) 
}; 

Task.WaitAll(tasks, 5000); 

私はWaitAll()のために5000のタイムアウトを入れて、なぜあなたはおそらく疑問に思っています。これは、TPLがタスクの終了を検出しないため、呼び出しスレッドが無期限に待機するためです。 ffmpeg.exeは、エンコーディングの途中で "停止"を処理し、CPUの0%で稼働し続けます。

TPLとProcessは矛盾していると思います。 TPLで各タスクのステータスを取得すると、常に「実行中」のままです。私は、アプリケーションをクラッシュさせないようにし、成功と失敗を管理したいので、TPL(またはその他のメカニズム)を使ってffmpegプロセスの実際のイベントをキャプチャしたいと思います。

+0

ffmpegプロセスは終了していますか?つまり、タスクを使わずに同じコードを実行した場合、終了しますか? –

+0

したがって、問題はTPLとは関係ありません。問題は、ffmpegが終了していないことです。正しい? – usr

答えて

0

問題がTPLであるか、プロセスが終了するかどうかを検出するために使用される自家製のメカニズムが原因であるかどうかわかりません。私は本当の理由は、待機が不定ではなく、特定のリソースへの圧力のためにスラッシングの古典的な場合であると考えています。

何が起こっているのか、CPUが低レベルであるように見える場合、あなたの圧力はIOまたはメモリの可能性が高いです。パフォーマンスカウンターを最低限使用してアプリケーションをプロファイリングすることをお勧めします(そして、表面レベルのクイックルックとしてタスクマネージャーを使用して)何が起きているのかを調べることをお勧めします。

コメント者が示唆しているように、タスクを排除し、少なくとも2つ以上のシリアル呼び出しをエンコードするかどうかを判断することは理にかなっています。リソースの問題ではなく、1つの特定の呼び出しがすべてを保持している可能性があります(エンコーディングのバグなど)。

関連する問題