【问题标题】:c# running multiple process.Start() asynchronouslyc#异步运行多个process.Start()
【发布时间】:2019-03-25 17:06:48
【问题描述】:

我有一个文件夹,其中包含多个需要转换为 PDF 的 PCL 文件。我可以使用第三方 exe 来实现这一点。为了加快速度,我尝试运行多个 Tasks(),每个 Tasks() 都使用 exe 启动一个新的 System.Diagnostics.Process;

System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = $@".\WinPCLtoPDF\WinPCLtoPDF.exe";
            process.StartInfo.Arguments = $@"{StepParameters["StagingFileName"]} {StepParameters["StagingFileName"]}.pdf batch";
            process.Start();
            process.WaitForExit();

任务被添加到List<Task>,每个任务都在程序退出前等待。

            foreach (FileInfo fileInfo in files)
            {
                tasks.Add(ProcessDocumentTaskAsync(batchType, fileInfo, deleteOriginalFile));

                while (tasks.Count < files.Count() && tasks.Where(x => !x.IsCompleted).Count() > concurrentTasks)
                {
                    Thread.Sleep(50);
                }
            }

任务是使用这样的方法创建的。

        private async static Task ProcessDocumentTaskAsync(BatchType batchType, FileInfo fileInfo, bool deleteOriginalFile)
        {
            await Task.Run(() =>
            {   
                ProcessParameters processParameters = ProcessParams();/////get process params            
                DocumentProcessor documentProcessor = GetDocumentProcessor(batchType, processParameters);
                using (documentProcessor)
                {
                    documentProcessor.ProcessDocument();
                }
            });
        }

此模式适用于其他任务,您可以从日志文件中看到作业正在异步执行。但是,使用此 WinPCLtoPDF.exe,它似乎一次只处理一个文件,但任务管理器显示有多个进程正在运行。例如,进程 1 和 2 将等待,而 3 开始并完成并被 4、5 等替换,直到最终整个文件夹完成,1 然后 2 完成。

我能否找出为什么 1 和 2 似乎被阻止并且没有快速完成,从而允许其他任务开始?

【问题讨论】:

  • 如果您可以包括如何创建任务会有所帮助。
  • @gpro 我添加了一些用于创建任务的代码。感谢您的帮助。
  • 你可能想使用这样的东西来避免占用线程/任务:gist.github.com/lassevk/f78b5cb354c259fa1242ad4c1141ad23
  • 另外,请不要尝试发明自己的调度机制,使用内置的东西,例如Parallel.ForEachActionBlock&lt;T&gt;。这些将允许您控制并发性。
  • 可能是这个有用的 exe 具有某些必须独占使用的资源,这限制了可以同时运行的副本数。如果您尝试使用例如启动多个副本会发生什么批处理文件?

标签: c# asynchronous task process.start


【解决方案1】:

最简单的解决方案可能是(如评论中所述)使用Parallel.ForEach。在您的情况下,它看起来像:

        Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, fileInfo =>
        {
            ProcessParameters processParameters = ProcessParams();/////get process params            
            DocumentProcessor documentProcessor = GetDocumentProcessor(batchType, processParameters);
            using (documentProcessor)
            {
                documentProcessor.ProcessDocument();
            }
        });

注意你的尝试:

它没有同时运行所有任务的原因可能是因为您在 ProcessDocumentTaskAsync 函数中等待任务完成。

【讨论】:

  • 这完美地工作并改进了我的代码,但不幸的是,对第三方 exe 的依赖意味着它实际上每台机器只能运行一个进程。我改用了这种模式。
猜你喜欢
  • 2011-04-15
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多