1. 程式人生 > WINDOWS開發 >C#簡單實現的階段性等待執行功能

C#簡單實現的階段性等待執行功能

有時候我們想要階段性執行操作,比如日誌輸出,不考慮資料丟失的問題,我們不想每個日誌都去寫一次硬碟,而是一段時間後一次性寫入,以及其他類似的需求

程式碼如下

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Concurrent;
using System.Text;

namespace ConsoleApp { class Program { static void Main(string[] args) { Logger logger = new Logger(); StageWaitTask<string> stageWaitTask = new StageWaitTask<string>((ps) => { StringBuilder sb = new StringBuilder();
foreach (var p in ps) { sb.Append(p + ","); } logger.Info(sb.ToString()); //日誌每次輸出浪費資源,所以我要累積一段時間的資料後,階段性執行 },2000); for (int i = 0; i < 99; i++) { stageWaitTask.PutParam(i.ToString()); //將日誌要資料的資訊扔到到階段性任務物件裡 Thread.Sleep(100
); } Console.ReadKey(); } } public class Logger { public void Info(string msg) { Console.WriteLine(msg); } } /// <summary> /// 階段性等待任務 /// </summary> public class StageWaitTask<T> { /// <summary> /// 引數的佇列 /// </summary> private Queue<T> queue = new Queue<T>(); private readonly object _lock = new object(); private Timer timer = null; private bool free = true; /// <summary> /// 等待的動作 /// </summary> private readonly Action<IList<T>> action = null; /// <summary> /// 等待的時長 /// </summary> private readonly int milliseconds = 0; /// <summary> /// 傳入等待執行的函式和時間間隔 /// </summary> public StageWaitTask(Action<IList<T>> action,int milliseconds) { timer = new Timer(Run); this.action = action; this.milliseconds = milliseconds; } /// <summary> /// 向佇列中放參數 /// </summary> public void PutParam(T data) { lock (_lock) { queue.Enqueue(data); if (free == true) { //只有在空閒的狀態下才允許下次等待,同一時間只允許一個延遲觸發 free = false; timer.Change(milliseconds,Timeout.Infinite); //等待milliseconds毫秒後執行Run } } } /// <summary> /// 等待執行的函式 /// </summary> private void Run(object arg) { lock (_lock) { action(queue.ToList()); //從佇列中拿去所有引數資料,執行外部傳入的階段性邏輯 queue.Clear(); //清空佇列 free = true; //置為空閒,可以觸發下一次等待 } } } }