最近想在使用.net 的隊列處理一些耗時的工做。通過考慮,須要先設計一個類,類中包含一個靜態的隊列。主要是寫隊列和讀取隊列。多線程
public class PaperCalculator { // 用於存放須要計算總分的試卷的計算任務的隊列 private static Queue<string> _paperQueue; // 用於通知是否有新試卷須要處理的「信號器」 private static ManualResetEvent _hasNew; // 用於寫日誌的線程 private static Thread _loggingThread; static PaperCalculator() { _paperQueue = new Queue<string>(); _hasNew = new ManualResetEvent(false); _loggingThread = new Thread(Process); _loggingThread.IsBackground = true; _loggingThread.Start(); } // 處理隊列中的任務 private static void Process() { while (true) { // 等待接收信號,阻塞線程。 _hasNew.WaitOne(); // 接收到信號後,重置「信號器」,信號關閉。 _hasNew.Reset(); Calculate(); } } private static void Calculate() { var i = 0; while(_paperQueue.Count <= 0) { File.AppendAllText("d:\\paper-calculate-log.txt", DateTime.Now + ": 空循環-" + i + Environment.NewLine); _hasNew.Reset(); Thread.Sleep(200); } string paperGuid =_paperQueue.Count>0?_paperQueue.Dequeue():"未獲取到paperGuid";//從隊列的開始出返回一個對象; File.AppendAllText("d:\\paper-calculate-log.txt", DateTime.Now + ":" + paperGuid + "客觀分數計算完成" + "當前隊列數目:" + _paperQueue.Count + Environment.NewLine); _hasNew.Set(); } static bool isFirst = true; // 公開一個Add方法,用於向隊列中添加內容而後供外部調用 public static void Add(string paperGuid) { _paperQueue.Enqueue(paperGuid); if (isFirst) { isFirst = false; _hasNew.Set(); } } }
2.添加一個調用的入口:ui
public class HomeController : Controller { public ActionResult Index() { Task.Run(() => { for (var i = 0; i < 500; i++) { PaperCalculator.Add(i+"----index-task-sj" + Guid.NewGuid().ToString()); Thread.Sleep(1000); } }); return View(); } }
訪問Home/Index,頁面迅速結束,task的多線程任然繼續工做,直到循環500次後結束,或者IIS重啓後。spa