如何在asp.net中使用多線程及隊列,異步處理一個耗時的任務(原創)

最近想在使用.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

相關文章
相關標籤/搜索