標籤:
在很多情境中我們需要通過並行化的方式來提高程式啟動並執行速度,比較典型的需求就是並行下載。前期遇到一個需求是要批量下載瓦片,每次大概下載上百萬個瓦片,要想提高瓦片的下載速度,只能通過並行化的方式,下面把我解決此問題的思路和代碼總結如下:
第一步確定線程個數(ThreadCount),這個要根據網路情況和硬體設定進行確定,可以做成一個配置項由使用者自行確定。
第二步將任務分成ThreadCount個,此步需要注意處理任務數較少(小於線程個數)以及任務數除不盡ThreadCount的情況。處理方式為任務數較少時不進行任務細分,由一個線程處理;除不盡的情況解決方案是最後一個任務處理剩下所有的任務。具體代碼如下:
1 var list_thread = new List<List<Location>>();//細分的下載任務(均分) 2 3 if (list.Count >= 1000)//如果比1000個還小不細分,一個線程執行 4 { 5 var count = (int)(list.Count / threadCount); 6 for (int i = 0; i < threadCount; i++) 7 { 8 if (i == threadCount - 1) 9 list_thread.Add(list.Skip(i * count).Take(list.Count - count * (threadCount - 1)).ToList());//最後一個取剩下的所有10 else11 list_thread.Add(list.Skip(i * count).Take(count).ToList());12 }13 }14 else15 list_thread.Add(list);
其中list_thread是細分後的工作清單,list是原始任務。
第三步處理所有任務,並添加到線程列表,等待所有線程執行完畢,即為所有任務處理完畢,具體代碼如下:
1 var list = ...;//擷取所有任務2 var list_thread = GetThreadCountList(loc_list);//擷取細分的線程任務3 4 var listTask = new List<Task>();//儲存所有線程任務5 foreach (var item in list_thread)//幾個細分任務就建立幾個線程6 {7 listTask.Add(Task.Factory.StartNew(() => DoWork(item)));//處理單個線程8 }9 Task.WaitAll(listTask.ToArray());//等待所有線程處理完畢!
以上就是使用Parallel進行並行化編程的方式,看似簡單的代碼,其實蘊藏了一個哲學問題(所有問題上升到一定程度都是哲學問題)——做事要細分:將一件複雜的事情盡量根據實際情況進行細分,完成一件一件小的任務,整個任務也就完成了。
另最近事情比較多,思緒有些混亂,忘見諒!
Parallel並行化編程