在實(shí)際應(yīng)用中,經(jīng)常要讓多個(gè)方法并行執(zhí)行以節(jié)約運(yùn)行時(shí)間,線程就是必不可少的了,而多線程的管理經(jīng)常又是一件頭疼的事情,比如方法并行執(zhí)行異步的返回問題,方法并行執(zhí)行的超時(shí)問題等等,因此這里分享一個(gè)簡易的、輕量級(jí)的方法并行執(zhí)行線程輔助類。
線程管理輔助類的兩個(gè)目標(biāo):
1、多個(gè)線程方法并行執(zhí)行,主線程等待,需要知道所有子線程執(zhí)行完畢;
2、異步執(zhí)行方法需要設(shè)置超時(shí)時(shí)間,超時(shí)可以跳過該方法,主線程直接返回;
3、輕量級(jí),雖然微軟提供了線程等待、超時(shí)等可用組件,如ManualResetEvent,但那是內(nèi)核對(duì)象,占用系統(tǒng)資源較多。
設(shè)計(jì)實(shí)現(xiàn):
1、該類內(nèi)部維護(hù)兩個(gè)變量,異步執(zhí)行方法總線程數(shù)totalThreadCount,當(dāng)前執(zhí)行完畢線程數(shù)據(jù)currThreadCount;
2、兩個(gè)開放方法,WaitAll等待執(zhí)行,SetOne設(shè)置方法執(zhí)行結(jié)束,每一個(gè)方法執(zhí)行完畢調(diào)用SetOne,currThreadCount數(shù)量加1,同時(shí)WaitAll判斷currThreadCount與totalThreadCount是否相等,相等即表示所有方法執(zhí)行完畢,返回;
3、為了實(shí)現(xiàn)線程安全,currThreadCount的變量處理使用Interlocked。
代碼實(shí)現(xiàn):

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace Loncin.CodeGroup10.Utility 8 { 9 public class ThreadHelper10 {11 /// <summary>12 /// 總線程數(shù)13 /// </summary>14 PRivate int totalThreadCount;15 16 /// <summary>17 /// 當(dāng)前執(zhí)行完畢線程數(shù)18 /// </summary>19 private int currThreadCount;20 21 /// <summary>22 /// 構(gòu)造函數(shù)23 /// </summary>24 /// <param name="totalThreadCount">總線程數(shù)</param>25 public ThreadHelper(int totalThreadCount)26 {27 Interlocked.Exchange(ref this.totalThreadCount, totalThreadCount);28 Interlocked.Exchange(ref this.currThreadCount, 0);29 }30 31 /// <summary>32 /// 等待所有線程執(zhí)行完畢33 /// </summary>34 /// <param name="overMiniseconds">超時(shí)時(shí)間(毫秒)</param>35 public void WaitAll(int overMiniseconds = 0)36 {37 int checkCount = 0;38 39 // 自旋40 while (Interlocked.CompareExchange(ref this.currThreadCount, 0, this.totalThreadCount) != this.totalThreadCount)41 {42 // 超過超時(shí)時(shí)間返回43 if (overMiniseconds > 0)44 {45 if (checkCount >= overMiniseconds)46 {47 break;48 }49 }50 51 checkCount++;52 53 Thread.Sleep(1);54 }55 }56 57 /// <summary>58 /// 設(shè)置信號(hào)量,表示單線程執(zhí)行完畢59 /// </summary>60 public void SetOne()61 {62 Interlocked.Increment(ref this.currThreadCount);63 }64 }65 }View Code使用示例:

1 public class ThreadHelperTest 2 { 3 /// <summary> 4 /// 線程幫助類 5 /// </summary> 6 private ThreadHelper threadHelper; 7 8 public void Test() 9 {10 // 開啟方法方法并行執(zhí)行11 int funcCount = 5;12 13 this.threadHelper = new ThreadHelper(funcCount);14 15 for (int i = 0; i < funcCount; i++)16 {17 Action<int> action = new Action<int>(TestFunc);18 action.BeginInvoke(i, null, null);19 }20 21 // 等待方法執(zhí)行,超時(shí)時(shí)間12ms,12ms后強(qiáng)制結(jié)束22 threadHelper.WaitAll(12);23 24 Console.WriteLine("所有方法執(zhí)行完畢!");25 }26 27 private void TestFunc(int i)28 {29 try30 {31 Console.WriteLine("方法{0}執(zhí)行!");32 Thread.Sleep(10);33 }34 finally35 {36 // 方法執(zhí)行結(jié)束37 this.threadHelper.SetOne();38 }39 }40 }View Code總結(jié):
1、該線程幫助類只是一個(gè)簡易的線程管理類,還缺少很多功能,比如異常處理等,不過一般的情況下還是比較使用的。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注