最近想在使用.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.添加一个调用的入口:
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重启后。