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

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

實現代碼:

            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(3
0 * 1000); cursor++; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM