当前位置:首页 > C#编程 > C#/.net框架 > 正文内容

C#:多进程开发,控制进程数量

Jorge2年前 (2022-05-08)C#/.net框架715

正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下:

C#
System.Threading.Tasks.Task task=System.Threading.Tasks.Task.Factory.StartNew(
                        (object mystate) =>
                        {
                            Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString());
                            process.WaitForExit();
                        }
                       , collectPathItems.Dequeue())

使用c#中的Process开启线程,并运行一个c#编译的一个Console的业务工程,Console.exe通过接收参数决定并行进程中的每个进程处理具体的任务:例如,实现一个多进程下载,传递给每个进程.exe的参数就是待采集的路径。

一般开辟的进程任务数也是要有限制的开,比如开辟进程数与计算机内核数一样Enviroment.ProcessCount。那么问题来了

问题一:如何在一个c#业务代码确保同时运行的进程数量确保尽量都是最大进程数呢?

假设:我们有25个带下待的任务,有的任务是1个小时左右才能完成、有的10分钟就完成了,如何确保一个完整的业务代码中去确保10分钟完成后,发现当前的进程数还未达到最大数,而且还有待处理任务,就继续开辟新的下载进程任务。

问题二:上边提到的进程最大数,也包含计算机中其他用户开辟的进程数。

假设用A:已经开辟了3个AutoCollectMrMultipleProcess.exe,用户B去进行自己的采集任务时,允许开辟的进程数为:Enviroment.ProcessCount-3(如果该值已经小于等于0,就不再开辟,进入等待)。

问题三:如何确保业务处理是同步的。

实现代码:

C#
int maxProcessCount = Enviroment.ProcessCount;
            List<System.Threading.Tasks.Task> taskItems = new List<System.Threading.Tasks.Task>();
            Queue<string> collectPathIetms=new Queue<string>();            // 初始化下载任务记录start            。。。            // 初始化下载任务记录end
            int cursor = 0;
            while (!(collectPathItems.Count == 0 && taskItems.Count == 0))
            {
                foreach (System.Threading.Tasks.Task taskItem in new List<System.Threading.Tasks.Task>(taskItems))
                {
                    if (taskItem.Status == System.Threading.Tasks.TaskStatus.Canceled                        || taskItem.Status == System.Threading.Tasks.TaskStatus.Faulted                        || taskItem.Status == System.Threading.Tasks.TaskStatus.RanToCompletion)
                    {
                        taskItems.Remove(taskItem);
                    }
                }

                // 如果collectPathItems.Count == 0,则不会有新的任务被添加进来,因此不需要执行下边其他代码。
                // 而只需要等待上边的任务完成跳出循环即可。
                if (collectPathItems.Count == 0)
                {
                    Thread.Sleep(30 * 1000);
                    continue;
                }

                Process[] processItems = Process.GetProcessesByName("AutoCollectMrMultipleProcess");
                if (processItems.Length >= maxProcessCount)
                {
                    Thread.Sleep(30 * 1000);
                    continue;
                }

                int dequeueCount = ((maxProcessCount - processItems.Length) > collectPathItems.Count) ? collectPathItems.Count : (maxProcessCount - processItems.Length);

                for (int i = 0; i < dequeueCount; i++)
                {
                    taskItems.Add(System.Threading.Tasks.Task.Factory.StartNew(
                        (object mystate) =>
                        {
                            Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString());
                            process.WaitForExit();
                        }
                       , collectPathItems.Dequeue())
                       );
                }
                                // sleep 30 seconds...
                Thread.Sleep(30 * 1000); 
                cursor++;
            }


#转载请注明出处 www.skcircle.com 《少有人走的路》勇哥的工业自动化技术网站。


扫描二维码推送至手机访问。

版权声明:本文由7点博客发布,如需转载请注明出处。

本文链接:http://6dot.cn/?id=48

标签: .NET.NET框架
分享给朋友:

“C#:多进程开发,控制进程数量” 的相关文章

C# 控件闪烁问题的解决

C# 控件闪烁问题的解决

说一下解决C#下控件闪烁的几个问题,如下:  listview和datagridview显示数据闪烁 自定义控件的显示闪烁listbox滚动条拖动闪烁面板中控件过多的闪烁propertyGrid点击和修改项目缓慢的问题richtextbox控件的刷新显示问题此类问题对于界面复杂规...

C#测量程序运行时间及cpu使用时间

C#测量程序运行时间及cpu使用时间

对一个服务器程序想统计每秒可以处理多少数据包,要如何做?答案是用处理数据包的总数,除以累记处理数据包用的时间。这里要指出的是, 运行一段程序,使用的cpu时间,跟实际运行的时间是不一样的。附例如下:C#private void ShowRunTime() {...

C# 异步和等待,async/await

C# 异步和等待,async/await

 首先,重点是:异步将从根本上改变大多数代码的编写方式。是的,我相信 async/await 会比 LINQ 产生更大的影响。理解异步将在短短几年内成为基本必需品。关键字介绍让我们直接开始吧。我将使用一些稍后将阐述的概念——请继续阅读第一部分。异步方法看起来像这样:public ...

.NET(C#) TPL:Task中未觉察异常和TaskScheduler.UnobservedTaskException事件

.NET(C#) TPL:Task中未觉察异常和TaskScheduler.UnobservedTaskException事件

当你在一个Task执行中抛出异常,比如:C#Task.Factory.StartNew(() =>{    throw new Exception();});运行该方法,没有任何异常抛出。事实上此时Task的异常处于未觉察状...

细说进程、应用程序域与上下文之间的关系(一)——进程的概念与作用

细说进程、应用程序域与上下文之间的关系(一)——进程的概念与作用

引言本文主要是介绍进程(Process)、应用程序域(AppDomain)、.NET上下文(Context)的概念与操作。虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提高系统的性能有莫大的帮助。在本篇最后的一节当中将会介绍到三者与线程之间的关系,希望对多线程开发人员能提供...

C# await、UI和死锁的问题

C# await、UI和死锁的问题

开发人员对Asnync 异步机制的兴趣程度很高。当然,任何新技术都必然会出现一些小问题。我现在多次看到的一个问题是开发人员通过阻止他们的 UI 线程意外地使他们的应用程序死锁,所以我认为花一些时间来探索这种情况的常见原因以及如何避免这种困境是值得的。就其核心而言,新的异步语言功能旨在恢复开发人员编写...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。