(C#)使用隊列(Queue)解決簡單的並發問題


有一個場景:一個搶購的項目,如果有5件商品。誰先搶到誰能夠買,可是如果此時此刻(這里的此時此刻如果是同樣的時間),有100人去搶這個商品,如果使用平時的方法會出現什么情況呢?你懂的。這里所說是就是有關並發的問題。

平時我們去超市購物去結賬的時候就是排隊,這里我們先讓搶購人排好隊,按時間,誰先點擊的搶購button誰就排在前面,這樣就形成了一個隊列,然后我們再對這個隊列處理。這樣就不會出現並發的問題了。

(至少能夠處理這樣簡單的並發,這里不討論太復雜的並發)

案例:

 

要求:有一個公布文章的接口。每公布一篇文章,調用一下接口。

(這里不用批量公布,為了解說這個)

 

建立一個這種處理程序類,BusinessInfoHelper.cs

 

namespace MyNameSpace 

{
    //隊列暫時類
    public class QueueInfo
    {
        public string medias { get; set; }
        public string proids { get; set; }
        public string host { get; set; }
        public string userid { get; set; }
        public string feedid { get; set; }
    }

    public class BusinessInfoHelper
    {
        #region 解決公布時含有優質媒體時。前台頁面卡住的現象
        //原理:利用生產者消費者模式進行入列出列操作

        public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper();
        private BusinessInfoHelper()
        { }

        private Queue<QueueInfo> ListQueue = new Queue<QueueInfo>();

        public void AddQueue(string medias, string proids, string host, string userid, string feedid) //入列
        {
            QueueInfo queueinfo = new QueueInfo();

            queueinfo.medias = medias;
            queueinfo.proids = proids;
            queueinfo.host = host;
            queueinfo.userid = userid;
            queueinfo.feedid = feedid;
            ListQueue.Enqueue(queueinfo);
        }

        public void Start()//啟動
        {
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start();
        }

        private void threadStart()
        {
            while (true)
            {
                if (ListQueue.Count > 0)
                {
                    try
                    {
                        ScanQueue();
                    }
                    catch (Exception ex)
                    {
                        LO_LogInfo.WLlog(ex.ToString());
                    }
                }
                else
                {
                    //沒有任務,歇息3秒鍾
                    Thread.Sleep(3000);
                }
            }
        }

        //要運行的方法
        private void ScanQueue()
        {
            while (ListQueue.Count > 0)
            {
                try
                {
                    //從隊列中取出
                    QueueInfo queueinfo = ListQueue.Dequeue();

                    //取出的queueinfo就能夠用了,里面有你要的東西
                    //下面就是處理程序了
                    //。

。。。

。 } catch (Exception ex) { throw; } } } #endregion } }

 

以上頁面寫好后。在程序開始執行時就得啟動這個線程去不停的處理任務,那么我們在Global的Application_Start里能夠這樣寫:

//啟動公布優質媒體程序
MyNameSpace.BusinessInfoHelper.Instance.Start();


有一個問題出來了。假設我處理完隊列中的一條記錄后。想返回這條記錄的ID,這個程序好像不能完畢。我就使用了還有一個方法 Lock方法 ,把方法鎖定,詳細的例如以下,

 

在頁面中定義全局的鎖:

private static object lockObject= new Object();

 

在方法 中這樣調用:

lock(lockObject)

{

//........

}


假設不使用另外一種方法的全局鎖,不知各位大俠有沒有好的解決的方法,假設有,能夠跟貼,很感謝。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM