最近想在使用.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重启后。

 

posted on 2016-06-14 20:25  踏歌&而行  阅读(7322)  评论(1编辑  收藏  举报