Ich habe versucht, ein Problem für mehrere Tage zu lösen. Ich bin ein Anfänger im Multithreading. Mein Ziel ist es, mehrere Video-Encoding-Aufgaben gleichzeitig mit ffmpeg.exe
auszuführen und die ganze Leistung des Servers zu nutzen.Verwenden von Task Parallel Library (C# .NET 4.0) mit einer externen exe (ffmpeg) ohne Konflikte
ich eine C# Wrapper haben, die den ffmpeg.exe
Prozess startet und arbeitet ohne (oder mit ffmpeg Innengewinde nur (nicht für flv-Codierung)) Einfädeln, die wie folgt aussieht:
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;
}
Der Code unten ruft den Wrapper auf. Der zweite Parameter jeder Encode
-Methode ist die Anzahl der Threads, die für das interne ffmpeg-Threading verwendet werden sollen. Wenn ich es deaktiviere, funktioniert es nicht.
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);
sind Sie wahrscheinlich fragen, warum ich für WaitAll()
ein Timeout von 5000 setzen. Dies liegt daran, dass der aufrufende Thread unbegrenzt wartet, da TPL kein Ende der Aufgaben erkennt. ffmpeg.exe
verarbeitet "Stop" in der Mitte der Codierung und läuft mit 0% der CPU weiter.
Ich denke, TPL und Process
sind widersprüchlich. Wenn ich den Status jeder Aufgabe mit TPL erhalte, bleibt sie ständig in Betrieb. Ich möchte die tatsächlichen Ereignisse von ffmpeg-Prozessen mit TPL (oder einem anderen Mechanismus) erfassen, weil ich verhindern möchte, dass die Anwendung abstürzt und Erfolge und Fehler verwalten möchte.
Beenden die ffmpeg-Prozesse? wenn Sie den gleichen Code ohne eine Aufgabe um ihn herum ausgeführt haben, wird es beendet? –
Also hat das Problem nichts mit TPL zu tun. Das Problem ist, dass ffmpeg nicht beendet wird. Richtig? – usr