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