只有1个进程显示并行foreach的活动

时间:2018-01-18 18:30:23

标签: c# .net ffmpeg process

所以我使用的是Parallel.Foreach,因为我想启动4个基本相同的独特进程。水印视频。

它应该如何工作是它应该打开4个ffmpeg.exe并将参数传递给每个窗口,以便一次为4个视频添加水印。 然而..那不是正在发生的事情,它打开了4个进程,但只有1个进程正在运行。不确定它是否试图使用相同的4次或者它可能是什么但是我需要帮助。

当我关闭工作过程时,3个不工作的工作程序仍在那里,直到我手动关闭它们。 这是一个直观的表示

pic1

这是第二张图片,显示关闭工作时发生的事情

以下是代码:

public void Watermark()
    {
        Console.WriteLine("Please enter the directory with the mp4 files: ");
        string EntryPath = Console.ReadLine();

        //Console.WriteLine("Please enter the directory with the mp4 files: ");
        //string OutputPath = Console.ReadLine();

        var psi = new ProcessStartInfo();
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.FileName = "ffmpeg.exe";
        int i = 0;

        var videos = Directory.EnumerateFiles(EntryPath, "*.mp4");
        Parallel.ForEach(videos, new ParallelOptions { MaxDegreeOfParallelism = 4 },
            vid =>
            {
                try
                {
                    //Maybe those processes are trying to work on the same file and can't access it?
                    //It's probably better to use the event Exited than WaitForExit
                    psi.Arguments = $"-i {vid} -i watermarker.png -threads 4 -filter_complex \"overlay = 275:350\" C:\\Users\\Developer\\Desktop\\Eh\\Watermarked{i}.mp4";
                    var p = Process.Start(psi);
                    p.WaitForExit();

                    Console.WriteLine($"{vid} is watermarked");
                    i++;
                }
                catch (Exception)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Error parsing that file");
                    Console.ForegroundColor = ConsoleColor.White;
                }

            });
        Console.ReadLine();

    }

1 个答案:

答案 0 :(得分:0)

您的增量(i++)是错误的,因此所有进程都会尝试输出到同一个文件(Watermarked0.mp4),因为i在给定当前代码时保持为0。你需要像这样使用Interlocked.Increment(ref i)

Parallel.ForEach(videos, new ParallelOptions { MaxDegreeOfParallelism = 4 },
        vid =>
        {
            try
            {
                //Maybe those processes are trying to work on the same file and can't access it?
                //It's probably better to use the event Exited than WaitForExit
                psi.Arguments = $"-i {vid} -i watermarker.png -threads 4 -filter_complex \"overlay = 275:350\" C:\\Users\\Developer\\Desktop\\Eh\\Watermarked{Interlocked.Increment(ref i)}.mp4";
                var p = Process.Start(psi);
                p.WaitForExit();

                Console.WriteLine($"{vid} is watermarked");
            }
            catch (Exception)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error parsing that file");
                Console.ForegroundColor = ConsoleColor.White;
            }

        });
    Console.ReadLine();

我怀疑这就是为什么只有一个进程处于活动状态的原因。但你不能使用Guid或其他东西作为文件名的独特部分来避免计数器,因为你不应该在Parallel.ForEach中拥有共享状态吗?

另见this Q& A。