您好,登錄后才能下訂單哦!
這篇文章主要講解了“C#線程完成數(shù)實(shí)例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C#線程完成數(shù)實(shí)例分析”吧!
假如,程序需要向一個(gè) Web 發(fā)送 5 次請(qǐng)求,受網(wǎng)路波動(dòng)影響,有一定幾率請(qǐng)求失敗。如果失敗了,就需要重試。
示例代碼如下:
class Program { private static int count = 0; static void Main(string[] args) { for (int i = 0; i < 5; i++) new Thread(HttpRequest).Start(); // 創(chuàng)建線程 // 用于不斷向另一個(gè)線程發(fā)送信號(hào) while (count < 5) { Thread.Sleep(100); } Console.WriteLine("任務(wù)執(zhí)行完畢"); } // 模擬網(wǎng)絡(luò)請(qǐng)求 public static void HttpRequest() { Console.WriteLine("開始一個(gè)任務(wù)"); // 隨機(jī)生成一個(gè)數(shù),如果為偶數(shù),則模擬請(qǐng)求失敗 bool isSuccess = (new Random().Next(0, 10)) % 2 == 0; // ... ...模擬請(qǐng)求 HTTP Thread.Sleep(TimeSpan.FromSeconds(2)); // 請(qǐng)求失敗則重試 if (!isSuccess) { Console.WriteLine($"請(qǐng)求失敗,count={count}"); new Thread(() => { HttpRequest(); }).Start(); return; } // 完成一次任務(wù),+1 Interlocked.Add(ref count,1); Console.WriteLine($"完成任務(wù),count={count}"); } }
代碼太糟糕了,但我們可以使用 CountdownEvent 類來改造它。
表示在計(jì)數(shù)變?yōu)榱銜r(shí)處于有信號(hào)狀態(tài)的同步基元。
也就是說,設(shè)定一個(gè)計(jì)數(shù)器,每個(gè)線程完成后,就會(huì)減去 1 ,當(dāng)計(jì)數(shù)器為 0 時(shí),代表所有線程都已經(jīng)完成了任務(wù)。
CountdownEvent 類的構(gòu)造函數(shù)如下:
構(gòu)造函數(shù) | 說明 |
---|---|
CountdownEvent(Int32) | 使用指定計(jì)數(shù)初始化 CountdownEvent 類的新實(shí)例。 |
CountdownEvent 類的常用方法如下:
方法 | 說明 |
---|---|
AddCount() | 將 CountdownEvent 的當(dāng)前計(jì)數(shù)加 1。 |
AddCount(Int32) | 將 CountdownEvent 的當(dāng)前計(jì)數(shù)增加指定值。 |
Reset() | 將 CurrentCount 重置為 InitialCount 的值。 |
Reset(Int32) | 將 InitialCount 屬性重新設(shè)置為指定值。 |
Signal() | 向 CountdownEvent 注冊(cè)信號(hào),同時(shí)減小 CurrentCount 的值。 |
Signal(Int32) | 向 CountdownEvent 注冊(cè)多個(gè)信號(hào),同時(shí)將 CurrentCount 的值減少指定數(shù)量。 |
TryAddCount() | 增加一個(gè) CurrentCount 的嘗試。 |
TryAddCount(Int32) | 增加指定值的 CurrentCount 的嘗試。 |
Wait() | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止。 |
Wait(CancellationToken) | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止,同時(shí)觀察 CancellationToken。 |
Wait(Int32) | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止,同時(shí)使用 32 位帶符號(hào)整數(shù)測(cè)量超時(shí)。 |
Wait(Int32, CancellationToken) | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止,并使用 32 位帶符號(hào)整數(shù)測(cè)量超時(shí),同時(shí)觀察 CancellationToken。 |
Wait(TimeSpan) | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止,同時(shí)使用 TimeSpan 測(cè)量超時(shí)。 |
Wait(TimeSpan, CancellationToken) | 阻止當(dāng)前線程,直到設(shè)置了 CountdownEvent 為止,并使用 TimeSpan 測(cè)量超時(shí),同時(shí)觀察 CancellationToken。 |
API 比較多,沒事,我們來慢慢了解它。
我們來編寫一個(gè)場(chǎng)景代碼,一個(gè)有五件事,需要完成,分別派出 5 個(gè)人去實(shí)現(xiàn)。
.Wait();
用在一個(gè)線程中,這個(gè)線程將等待其它完成都完成任務(wù)后,才能繼續(xù)往下執(zhí)行。
Signal();
用于工作線程中,向 CountdownEvent 對(duì)象發(fā)送信號(hào),告知線程已經(jīng)完成任務(wù),然后 CountdownEvent.CurrentCount
將減去 1。
當(dāng)計(jì)數(shù)器為 0 時(shí),阻塞的線程將恢復(fù)執(zhí)行。
代碼示例如下:
class Program { // 手頭上有 5 件事 private static CountdownEvent countd = new CountdownEvent(5); static void Main(string[] args) { Console.WriteLine("開始交待任務(wù)"); // 同時(shí)叫 5 個(gè)人,去做 5 件事 for (int i = 0; i < 5; i++) { Thread thread = new Thread(DoOne); thread.Name = $"{i}"; thread.Start(); } // 等他們都完成事情 countd.Wait(); Console.WriteLine("任務(wù)完成,線程退出"); Console.ReadKey(); } public static void DoOne() { int n = new Random().Next(0, 10); // 模擬要 n 秒才能完成 Thread.Sleep(TimeSpan.FromSeconds(n)); // 完成了,減去一件事 countd.Signal(); Console.WriteLine($" {Thread.CurrentThread.Name}完成一件事了"); } }
示例很簡單,每個(gè)線程在完成自己的任務(wù)時(shí),需要調(diào)用 Signal()
方法,使得計(jì)數(shù)器減去1。
.Wait();
可以等待所有的任務(wù)完成。
需要注意的是,如果不調(diào)用 Signal()
或者計(jì)數(shù)器一直不為0,那么 Wait()
將無限等待。
當(dāng)然,Wait()
可以設(shè)置等待時(shí)間,
另外我們也看到了常用方法中有 AddCount()
、Reset()
等。
這個(gè)類的等待控制方式比較寬松,Wait()
后,到底什么時(shí)候才能執(zhí)行,全憑其它線程自覺。
如果發(fā)現(xiàn)線程執(zhí)行任務(wù)失敗,我們可以不調(diào)用 Signal()
或者 使用 AddCount()
來增加次數(shù),進(jìn)行重試
感謝各位的閱讀,以上就是“C#線程完成數(shù)實(shí)例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C#線程完成數(shù)實(shí)例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。