多線程,隊列,先進先出、信號量...

来源:https://www.cnblogs.com/xuling-297769461/archive/2020/04/09/12664622.html
-Advertisement-
Play Games

某些場景併發量太高,需要採用隊列輔助,特此備註:多線程隊列,先進先出 某些情況也會用到阻塞當前線程,等待伺服器返回或者耗時的處理,這種情況,可採用信號量輔助 1 ManualResetEvent allDone = new ManualResetEvent(false);//初始化,開啟阻塞 2 a ...


某些場景併發量太高,需要採用隊列輔助,特此備註:多線程隊列,先進先出

某些情況也會用到阻塞當前線程,等待伺服器返回或者耗時的處理,這種情況,可採用信號量輔助

1 ManualResetEvent allDone = new ManualResetEvent(false);//初始化,開啟阻塞
2 allDone.Reset();//信號量重置,狀態為阻塞
3 allDone.WaitOne(5*1000);//阻塞當前線程,最大等待5秒
4 allDone.Set();//釋放信號量,將阻塞的線程繼續向下

口水話註解:調用了Set方法將事件設為true後,不會去調用Reset方法,這將導致事件一直處於true,其它等待的多個線程都會得到執行,直到你手動調用Reset方法。
相當於你把門打開後,需要手動去關(非自動門)。

 

1 AutoResetEvent ReciveResetEvent = new System.Threading.AutoResetEvent(true);//初始化,未開啟阻塞
2 ReciveResetEvent.WaitOne(30000);//阻塞
3 ReciveResetEvent.Set();//釋放後,自動開啟阻塞
口水話註解:調用了Set方法將事件設為true之後,其中一個等待線程得到執行後,它會自動調用Reset方法,將事件信號設為false,以阻塞其它的線程。
相當於放一個線程進來,門自動就關了(自動門)。

 

  1 /*
  2     例子:
  3         
  4     //初始化後臺處理消息線程
  5     AsyncQueueDataProcessor<string> asyncQueueDetector = new AsyncQueueDataProcessor<string>();
  6     asyncQueueDetector.ProcessData += AsyncQueue_ProcessData;//事件里處理有數據時
  7     asyncQueueDetector.Start();
  8 
  9     服務啟動後,使用 asyncQueueDetector.AppendData 追加數據到隊列
 10     */
 11 
 12 
 13     /// <summary>
 14     /// 非同步處理隊列數據
 15     /// </summary>
 16     /// <typeparam name="T"></typeparam>
 17     public class AsyncQueueDataProcessor<T> : IDisposable
 18     {
 19         #region 成員變數
 20 
 21         /// <summary>
 22         /// 待處理的數據隊列
 23         /// </summary>
 24         ConcurrentQueue<T> DataQueue;
 25 
 26         /// <summary>
 27         /// 數據處理定時器
 28         /// </summary>
 29         Timer processTimer;
 30 
 31         #endregion
 32 
 33         #region 構造函數
 34 
 35         /// <summary>
 36         /// 初始化
 37         /// </summary>
 38         /// <param name="intervalMillSecond"></param>
 39         public AsyncQueueDataProcessor(int intervalMillSecond = 120)
 40         {
 41             DataQueue = new ConcurrentQueue<T>();
 42             processTimer = new Timer(intervalMillSecond);
 43             processTimer.Elapsed += ProcessTimer_Elapsed;
 44             processTimer.AutoReset = false;
 45         }
 46 
 47         #endregion
 48 
 49         #region 自定義事件
 50 
 51         /// <summary>
 52         /// 數據拋出時觸發
 53         /// </summary>
 54         public event EventHandler<T> ProcessData;
 55 
 56         #endregion
 57 
 58         #region 公共方法
 59 
 60         /// <summary>
 61         /// 釋放所有資源
 62         /// </summary>
 63         public void Dispose()
 64         {
 65             processTimer.Dispose();
 66             ClearData();
 67         }
 68 
 69         /// <summary>
 70         /// 開始處理數據
 71         /// </summary>
 72         public void Start()
 73         {
 74             processTimer.Start();
 75         }
 76 
 77         /// <summary>
 78         /// 停止處理數據
 79         /// </summary>
 80         public void Stop()
 81         {
 82             processTimer.Stop();
 83         }
 84 
 85         /// <summary>
 86         /// 追加數據到隊列
 87         /// </summary>
 88         /// <param name="data"></param>
 89         public void AppendData(T data)
 90         {
 91             DataQueue.Enqueue(data);
 92         }
 93 
 94         /// <summary>
 95         /// 清空隊列數據
 96         /// </summary>
 97         public void ClearData()
 98         {
 99             do
100             {
101             } while (DataQueue.TryDequeue(out T t));
102         }
103         #endregion
104 
105         #region 事件
106 
107         //處理數據時執行
108         private void ProcessTimer_Elapsed(object sender, ElapsedEventArgs e)
109         {
110             T t;
111             if (DataQueue.TryDequeue(out t))
112             {
113                 if (ProcessData != null)
114                 {
115                     try
116                     {
117                         ProcessData(this, t);
118                     }
119                     catch (Exception exp)
120                     {
121                         Debug.WriteLine($"隊列裡面發生了未處理的異常-{exp.Message}\r\n{exp.StackTrace}");
122                     }
123                 }
124             }
125 
126             processTimer.Start();
127         }
128 
129         #endregion
130     }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 出問題的代碼如下: public class DBBookChaptersService : IBookChaptersService { private readonly BooksContext _booksContext; public DBBookChaptersService(BooksC ...
  • 因業務需要瞭解Modbus協議的使用,因此對Modbus的協議,以及相應的C#處理應用進行瞭解,針對協議的幾種方式(RTU、ASCII、TCPIP)進行了封裝,以及對Modbus的各種功能碼的特點進行了詳細的瞭解,本篇隨筆基於這些知識進行了一定的梳理和介紹,主要內容包括Modbus協議簡要介紹、Mo... ...
  • bootstrap paginator 分頁 效果圖 1. Demo前的準備 1.1. 編程環境 VS2019 1.2. 準備 分頁插件(bootstrap paginator)下載: https://github.com/lyonlai/bootstrap paginator 下載後找到 這個為該 ...
  • 在做劍指offer的題目時,發現每次需要用到樹做為參數來測試自己寫的方法時,都很是痛苦。於是乎就萌生了寫一個利用數據生成樹的方法。簡單測試了下,沒什麼毛病。在這裡貼出來,如果以後發現有bug了會持續在後面更新,也歡迎大家指出其中的不足。 using System; using System.Coll ...
  • 進程守護工具 1.寫在前面 經常寫一些服務程式,有時要監測服務程式的運行狀態,所以就做了一個進程守護工具。 2.分析 通過Process.GetProcessesByName(ProcessName),獲得指定進程列表。 用Process.MainModule.FileName來判斷程式是否運行。 ...
  • public partial class Form1 : Form { CancellationTokenSource cts = new CancellationTokenSource(); public Form1() { InitializeComponent(); } private voi ...
  • 很多人使用力軟敏捷框架的一個困擾就是表格控制項,力軟並沒有使用常規的jqgrid,而是用了自己的一套 jfgrid。所以今天在這做個簡單的說明,如果你有什麼疑問也可以在評論區提出來,後期的文章會做說明。 首先來講下jfgrid有哪些設置屬性: url 後臺請求地址 param 後臺請求參數 rowda ...
  • 1.環境 VS2019 16.5.1 .NET Core SDK 3.1.200 Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.預設綁定 2.1.使用方法 Blazor中Razor組件通過一個名為@bind的HTML元素屬性提供數據綁定功 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...