1. 程式人生 > >C#:多進程開發,控制進程數量

C#:多進程開發,控制進程數量

使用 star 其他 nvi 都是 ont tar obj proc

正在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,就不再開辟,進入等待)。

問題三:如何確保業務處理是同步的。

實現代碼:

            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(5 * 60 * 1000); continue; } Process[] processItems = Process.GetProcessesByName("AutoCollectMrMultipleProcess"); if (processItems.Length >= maxProcessCount) { Thread.Sleep(5 * 60 * 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(3
0 * 1000); cursor++; }

C#:多進程開發,控制進程數量