在自動化處理常遇到一個狀況是多線排程,例如有三條工作站,每一條工作站的處理能力不同,例如worker1可以處理加工時間<5,worker2可以處理加工時間5~10, 而worker3可以處理加工時間10~15,假設今天客戶的加工需要加工時間清單如下(jobID即加工時間)
int[] jobIDs = new int[] { 2, 3, 12, 5, 7, 3, 6, 10 };
接下來就是幾個判斷
1. 該生產線是否有能力處理目前工單
2. 該生產線是否忙線中
如果目前工作站有能力且非忙碌狀態則處理,否則該工單必須流向下一個工作站,直到有一個工作站有能力且有空處理為止。
工作計時器(WorkTimer類別)
1: using System.Timers;
2: using System.Threading;
1: class WorkTimer
2: {
3: protected System.Timers.Timer aTimer;
4: private int count = 0;
5: private int interval = 1000;
6: private int totalCount;
7: private int jobID;
8: private string workerName;
9: public int JobID { get { return jobID; } }
10: public bool IsBusy { get; set; }
11: public WorkTimer(string workerName, int jobID, int totalCount)
12: {
13: this.workerName = workerName;
14: this.totalCount = totalCount;
15: this.jobID = jobID;
16: SetTimer();
17: }
18: private void SetTimer()
19: {
20: IsBusy = true;
21: // Create a timer with a two second interval.
22: aTimer = new System.Timers.Timer(interval);
23: // Hook up the Elapsed event for the timer.
24: aTimer.Elapsed += OnTimedEvent;
25: aTimer.AutoReset = true;
26: aTimer.Enabled = true;
27: }
28: private void OnTimedEvent(Object source, ElapsedEventArgs e)
29: {
30: count++;
31: Console.WriteLine("{0}, jobID {1} ({2}/{3}) {4:HH:mm:ss.fff}", workerName,
32: jobID, count, totalCount, e.SignalTime);
33: if(count>=totalCount)
34: {
35: aTimer.Stop();
36: aTimer.Dispose();
37: IsBusy = false;
38: }
39: }
40: }
Handler抽象類別
1: abstract class Handler
2: {
3: public bool IsBusy
4: {
5: get {
6: if (wt == null) return false;
7: else return wt.IsBusy;
8: }
9: }
10: protected WorkTimer wt;
11: protected Handler nextHandler;
12: public int JobID { get { return wt.JobID; } }
13: public void SetNextHandler(Handler handler)
14: {
15: this.nextHandler = handler;
16: }
17: public abstract void Request(int jobID);
18: }
三個繼承Handler抽象類別,分別為Worker1Handler(可以處理加工時間<5)、Worker2Handler(可以處理加工時間5~10)、Worker3Handler(可以處理加工時間10~15)。
1: class Worker1Handler : Handler
2: {
3: public override void Request(int jobID)
4: {
5: if(jobID >= 0 && jobID < 5)
6: {
7: int totalCount = jobID;
8: if (!IsBusy)
9: {
10: Console.WriteLine("----------");
11: Console.WriteLine("{0} 開始處理 jobID = {1}", this.GetType().Name, jobID);
12: Console.WriteLine("----------");
13: wt = new WorkTimer(this.GetType().Name, jobID, totalCount);
14: }else if (nextHandler != null)
15: {
16: Console.WriteLine("***");
17: Console.WriteLine("{0} 正在處理jobID {1}中,無法處理 jobID = {2}", this.GetType().Name, this.JobID, jobID);
18: Console.WriteLine("***");
19: Thread.Sleep(1000);
20: nextHandler.Request(jobID);
21: }
22: }
23: else if(nextHandler !=null)
24: {
25: nextHandler.Request(jobID);
26: }
27: }
28: }
29: class Worker2Handler : Handler
30: {
31: public override void Request(int jobID)
32: {
33: if (jobID >= 5 && jobID < 10)
34: {
35: int totalCount = jobID;
36: if (!IsBusy)
37: {
38: Console.WriteLine("{0} 開始處理 jobID = {1}", this.GetType().Name, jobID);
39: wt = new WorkTimer(this.GetType().Name, jobID, totalCount);
40: }
41: else if (nextHandler != null)
42: {
43: Console.WriteLine("{0} 正在處理jobID {1}中,無法處理 jobID = {2}", this.GetType().Name, this.JobID, jobID);
44: Thread.Sleep(1000);
45: nextHandler.Request(jobID);
46: }
47: }
48: else if (nextHandler != null)
49: {
50: nextHandler.Request(jobID);
51: }
52: }
53: }
54: class Worker3Handler : Handler
55: {
56: public override void Request(int jobID)
57: {
58: if (jobID >= 10 && jobID < 15)
59: {
60: int totalCount = jobID;
61: if (!IsBusy)
62: {
63: Console.WriteLine("{0} 開始處理 jobID = {1}", this.GetType().Name, jobID);
64: wt = new WorkTimer(this.GetType().Name, jobID, totalCount);
65: }
66: else if (nextHandler != null)
67: {
68: Console.WriteLine("{0} 正在處理jobID {1}中,無法處理 jobID = {2}", this.GetType().Name, this.JobID, jobID);
69: Thread.Sleep(1000);
70: nextHandler.Request(jobID);
71: }
72: }
73: else if (nextHandler != null)
74: {
75: nextHandler.Request(jobID);
76: }
77: }
78: }
客戶端
1: Handler work1 = new Worker1Handler();
2: Handler work2 = new Worker2Handler();
3: Handler work3 = new Worker3Handler();
4: work1.SetNextHandler(work2);
5: work2.SetNextHandler(work3);
6: work3.SetNextHandler(work1);
7:
8: int[] jobIDs = new int[] { 2, 3, 12, 5, 7, 3, 6, 10 };
9: foreach (int jobID in jobIDs)
10: {
11: work1.Request(jobID);
12: }
13: Console.Read();
int[] jobIDs = new int[] { 2, 3, 12, 5, 7, 3, 6, 10 };
執行結果如下:
----------
Worker1Handler 開始處理 jobID = 2
----------
***
Worker1Handler 正在處理jobID 2中,無法處理 jobID = 3
***
***
Worker1Handler 正在處理jobID 2中,無法處理 jobID = 3
***
Worker1Handler, jobID 2 (1/2) 21:52:31.720
Worker1Handler, jobID 2 (2/2) 21:52:32.720
###############
----------
Worker1Handler 開始處理 jobID = 3
----------
Worker3Handler 開始處理 jobID = 12
Worker2Handler 開始處理 jobID = 5
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker1Handler, jobID 3 (1/3) 21:52:33.720
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker2Handler, jobID 5 (1/5) 21:52:33.725
Worker3Handler, jobID 12 (1/12) 21:52:33.725
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker2Handler, jobID 5 (2/5) 21:52:34.732
Worker3Handler, jobID 12 (2/12) 21:52:34.732
Worker1Handler, jobID 3 (2/3) 21:52:34.733
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker2Handler, jobID 5 (3/5) 21:52:35.732
Worker3Handler, jobID 12 (3/12) 21:52:35.732
Worker1Handler, jobID 3 (3/3) 21:52:35.732
###############
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker2Handler, jobID 5 (4/5) 21:52:36.733
Worker3Handler, jobID 12 (4/12) 21:52:36.733
Worker2Handler 正在處理jobID 5中,無法處理 jobID = 7
Worker2Handler, jobID 5 (5/5) 21:52:37.734
###############
Worker3Handler, jobID 12 (5/12) 21:52:37.734
Worker2Handler 開始處理 jobID = 7
----------
Worker1Handler 開始處理 jobID = 3
----------
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker3Handler, jobID 12 (6/12) 21:52:38.737
Worker2Handler, jobID 7 (1/7) 21:52:39.727
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker1Handler, jobID 3 (1/3) 21:52:39.746
Worker3Handler, jobID 12 (7/12) 21:52:39.746
Worker2Handler, jobID 7 (2/7) 21:52:40.727
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker1Handler, jobID 3 (2/3) 21:52:40.757
Worker3Handler, jobID 12 (8/12) 21:52:40.757
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker2Handler, jobID 7 (3/7) 21:52:41.740
Worker1Handler, jobID 3 (3/3) 21:52:41.772
###############
Worker3Handler, jobID 12 (9/12) 21:52:41.772
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker2Handler, jobID 7 (4/7) 21:52:42.742
Worker3Handler, jobID 12 (10/12) 21:52:42.772
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker2Handler, jobID 7 (5/7) 21:52:43.758
Worker3Handler, jobID 12 (11/12) 21:52:43.772
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker2Handler, jobID 7 (6/7) 21:52:44.772
Worker3Handler, jobID 12 (12/12) 21:52:44.772
###############
Worker2Handler 正在處理jobID 7中,無法處理 jobID = 6
Worker2Handler, jobID 7 (7/7) 21:52:45.773
###############
Worker2Handler 開始處理 jobID = 6
Worker3Handler 開始處理 jobID = 10
Worker2Handler, jobID 6 (1/6) 21:52:47.742
Worker3Handler, jobID 10 (1/10) 21:52:47.760
Worker2Handler, jobID 6 (2/6) 21:52:48.742
Worker3Handler, jobID 10 (2/10) 21:52:48.774
Worker2Handler, jobID 6 (3/6) 21:52:49.743
Worker3Handler, jobID 10 (3/10) 21:52:49.775
Worker2Handler, jobID 6 (4/6) 21:52:50.744
Worker3Handler, jobID 10 (4/10) 21:52:50.788
Worker2Handler, jobID 6 (5/6) 21:52:51.757
Worker3Handler, jobID 10 (5/10) 21:52:51.789
Worker2Handler, jobID 6 (6/6) 21:52:52.757
###############
Worker3Handler, jobID 10 (6/10) 21:52:52.790
Worker3Handler, jobID 10 (7/10) 21:52:53.790
Worker3Handler, jobID 10 (8/10) 21:52:54.790
Worker3Handler, jobID 10 (9/10) 21:52:55.791
Worker3Handler, jobID 10 (10/10) 21:52:56.792
###############
參考資料
1. Timer 類別
2. 大話設計模式, 作者: 程杰