Last active
October 27, 2020 12:03
-
-
Save edward-hsu-1994/b6b286a2ce8bfd02013ab05ef40c728d to your computer and use it in GitHub Desktop.
Thread搭配Queue實現多Worker任務分發
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Author: XuPeiYao | |
* License: MIT | |
* Summary: Thread搭配Queue實現多Worker任務分發 | |
*/ | |
using System; | |
using System.Collections.Concurrent; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Threading; | |
namespace SimpleQueueExample | |
{ | |
/// <summary> | |
/// 工作的內容包裝類別 | |
/// </summary> | |
class Job | |
{ | |
public string Something { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// 測試工作數量 | |
int jobCount = 100; | |
// Worker數量 | |
int workerCount = 3; | |
// 建立測試工作項目 | |
ConcurrentQueue<Job> jobs = new ConcurrentQueue<Job>( | |
Enumerable.Range(0, jobCount).Select(x => new Job() { Something = "Job_" + x.ToString() }) | |
); | |
// 計時器,計算總耗時 | |
Stopwatch stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
// 建立倒數事件 | |
using (CountdownEvent counter = new CountdownEvent(workerCount)) | |
{ | |
// 建立Worker | |
for (int i = 0; i < workerCount; i++) | |
{ | |
// 利用Tuple傳遞倒數事件以及工作Queue(可自己建立一個類別去包裝) | |
ThreadPool.QueueUserWorkItem(Runner, (counter, jobs)); | |
} | |
// 等候倒數至0的信號 | |
counter.Wait(); | |
} | |
stopwatch.Stop(); | |
Console.WriteLine("任務結束!"); | |
Console.WriteLine($"總耗時: {stopwatch.Elapsed}"); | |
} | |
static void Runner(object status) | |
{ | |
// 用來識別Thread用的ID而已 | |
Guid runnerId = Guid.NewGuid(); | |
// 自status取出外部傳遞進來的Counter與工作Queue | |
var inputData = ((CountdownEvent counter, ConcurrentQueue<Job> jobs))status; | |
// 循環自Queue中嘗試取出工作,無工作時跳脫 | |
while (inputData.jobs.TryDequeue(out Job jobForThisThread)) | |
{ | |
// 執行工作內容 | |
Console.WriteLine(runnerId + ": " + jobForThisThread.Something + " - START"); | |
Thread.Sleep(1000); | |
Console.WriteLine(runnerId + ": " + jobForThisThread.Something + " - FINSH"); | |
} | |
// 針對倒數事件送出倒數信號 | |
inputData.counter.Signal(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment