麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

如何簡易的提高吞吐量

2019-11-14 13:51:11
字體:
來源:轉載
供稿:網友

    性能提升還是那幾個要素,就像我在之前的博文里面提到的一樣,這一篇只是更加簡單一點而已。

    因為硬件配置是固定的,那我們只是簡單說一說在使用C#進行開發的項目中,如何使用一些簡單的小招數讓性能有一個比較大幅度的顯著提升。

    一、繞開那些煩人卻又不可避免的DB操作。

    DB操作是不可避免卻又是項目重中之中的所在,那我們可以做哪些優化呢?

    首先,根據業務將DB操作分為需要即時和非即時的兩塊,關于非即時的我們可以將其單獨的交給某一個線程來單獨慢慢處理。代碼如下:

public class DbActionQueue : IDisposable    {        public Queue<Action> _transQueue;        PRivate Thread _thread;        private bool _isDispose = false;        private static readonly object _syncObject = new object();        private readonly object _syncQueueObject = new object();        private static DbActionQueue _instance;        public static DbActionQueue Instance        {            get            {                if (_instance == null)                {                    lock (_syncObject)                    {                        if (_instance == null)                        {                            _instance = new DbActionQueue();                        }                    }                }                return _instance;            }        }        private DbActionQueue()        {            if (_transQueue == null)            {                _transQueue = new Queue<Action>();            }            if (_thread == null)            {                _thread = new Thread(Thread_Work)                {                    IsBackground = true                };            }            _thread.Start();        }        public void Push(Action action)        {            if (_transQueue == null) throw new ArgumentNullException("dbActionQueue is not init");            lock (_syncQueueObject)            {                _transQueue.Enqueue(action);            }        }        public void Thread_Work()        {            while (!_isDispose)            {                Action[] items = null;                if (_transQueue != null && _transQueue.Count > 0)                {                    lock (_syncQueueObject)                    {                        items = new Action[_transQueue.Count];                        _transQueue.CopyTo(items, 0);                        _transQueue.Clear();                    }                }                if (items != null && items.Length > 0)                {                    foreach (var item in items)                    {                        try                        {                            item.Invoke();                        }                        catch (Exception ex)                        {                            LogHelper.Write(string.Format("DbActionQueue error. | Exception.StackTrace:{0}", ex.StackTrace), ex);                        }                    }                }                Thread.Sleep(1);            }        }        public void Dispose()        {            _isDispose = true;            _thread.Join();        }    }
View Code

    通過代碼可以看到,我們在實例化的時候,單獨創建了一個線程,用來做處理。

    那對于一些像日志之類的操作,則可以通過以下代碼進行操作:

DbActionQueue.Instance.Push(() =>{    LogBLL.Instance.Add(new Log                        {                            action_time = DateTime.Now;                        });});            
View Code

    到這里不難免要問了,如果數據量過大,單個隊列已經無法滿足的時候,怎么做處理。關于隊列的監控,優化不在該文討論,通俗一點的做法可以引入一些第三方的隊列。另外在項目中,其實我們更多的時候,實際上并不是在Insert,Update,Delete等操作,而是Select的操作,那關于Select的一些緩存處理,也不在該文的討論范疇,因為關于Cache的各種中間件實在太多,而且篇幅太大。

    可能在某些時候,我們還是覺得單個線程處理太慢,希望多開幾個線程來處理對于DB的請求,則我們可以根據實際業務情況和機器配置,初始化任意個線程來處理,則以上代碼需要稍稍改裝一下,將單例的換成可自由實例化的,代碼如下:

 public class DbQueue    {        public Queue<Action> _transQueue;        private Thread _thread;        private bool _isDispose = false;        private readonly object _syncQueueObject = new object();        public DbQueue()        {            if (_transQueue == null)            {                _transQueue = new Queue<Action>();            }            if (_thread == null)            {                _thread = new Thread(Thread_Work)                {                    IsBackground = true                };            }            _thread.Start();        }        public void Thread_Work()        {            while (!_isDispose)            {                Action[] items = null;                if (_transQueue != null && _transQueue.Count > 0)                {                    lock (_syncQueueObject)                    {                        items = new Action[_transQueue.Count];                        _transQueue.CopyTo(items, 0);                        _transQueue.Clear();                    }                }                if (items != null && items.Length > 0)                {                    foreach (var item in items)                    {                        try                        {                            item.Invoke();                        }                        catch (Exception ex)                        {                            LogHelper.Write(string.Format("DbActionQueue error. | Exception.StackTrace:{0}", ex.StackTrace), ex);                        }                    }                }                Thread.Sleep(1);            }        }        public void Push(Action action)        {            if (_transQueue == null) throw new ArgumentNullException("dbActionQueue is not init");            lock (_syncQueueObject)            {                _transQueue.Enqueue(action);            }        }        public void Dispose()        {            _isDispose = true;            _thread.Join();        }    }
View Code

 那多個線程之間的處理,代碼則如下:

 public class DbQueueManage    {         private int _threadNumber = 2;        private DbQueue[] _dbQueues;        private Random random = new Random();        private DbQueueManage()        {                    }        static DbQueueManage()        {        }        private static readonly object _syncObject = new object();        private static DbQueueManage _instance;        public static DbQueueManage Instance        {            get            {                if (_instance == null)                {                    lock (_syncObject)                    {                        if (_instance == null)                        {                            _instance = new DbQueueManage();                        }                    }                }                return _instance;            }        }        public void Init(Action action, int threadNum = 2)        {            if (_dbQueues == null)            {                this._threadNumber = threadNum;                _dbQueues = new DbQueue[threadNum];                for (var i = 0; i < threadNum; i++)                {                    _dbQueues[i] = new DbQueue();                }            }        }        public void Push(Action action)        {            var index = GetRandomThreadIndex();            if (_dbQueues != null && _dbQueues.Length > index)            {                _dbQueues[index].Push(action);            }        }        public int GetRandomThreadIndex()        {            return random.Next(0, this._threadNumber);        }    }
View Code

另外關于為什么不選用Task來做處理,雖然Task關于線程的處理還是很優秀的,這里請各位同僚自行定奪。關于即時性的DB操作,則可以以Redis,MongoDb,或者自行編寫的緩存來作為中間件,然后再講具體入庫的操作,放入之前編寫好的隊列處理里面。

    


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 99热草| 在线看一区二区三区 | 亚洲精品成人18久久久久 | 国内精品久久久久久久久久 | 亚洲第一色片 | 久久久久久久久久久av | 亚洲电影在线观看高清免费 | 精品成人国产在线观看男人呻吟 | 久久亚洲精品久久国产一区二区 | 在线日韩亚洲 | 色综合久久久久久久粉嫩 | 国产一级午夜 | 少妇一级淫片免费看 | 国产91av视频 | 91精彩视频| 日本搞逼视频 | 热@国产| 日日草日日干 | 国产一区二区三区在线观看视频 | 九九热视频在线 | 黄色大片在线免费观看 | 免费视频99| 成人午夜小视频 | 蜜桃精品视频在线观看 | 欧美激情综合在线 | 美女视频黄视大全视频免费网址 | 久久精品亚洲精品国产欧美kt∨ | 毛片小网站 | 久久精品黄| 久国产 | 精品国产一区二区三区四区在线 | 国产精品视频成人 | 视频一区二区久久 | av免费在线不卡 | 蜜桃视频在线播放 | 国产日韩成人 | 污黄视频在线播放 | 久久99精品久久久久久国产越南 | 久草干 | 婷婷亚洲一区二区三区 | 亚洲精品午夜电影 |