C# 多線程與高併發處理並且具備暫停、繼續、停止功能

来源:https://www.cnblogs.com/wt-vip/archive/2019/09/27/11599059.html
-Advertisement-
Play Games

--近期有一個需要運用多線程的項目,會有併發概率,所以寫了一份代碼,可能有寫地方還不完善,後續有需求在改 1 /// <summary> 2 /// 併發對象 3 /// </summary> 4 public class MeterAsyncQueue 5 { 6 public MeterAsyn... ...


--近期有一個需要運用多線程的項目,會有併發概率,所以寫了一份代碼,可能有寫地方還不完善,後續有需求在改
1
/// <summary> 2 /// 併發對象 3 /// </summary> 4 public class MeterAsyncQueue 5 { 6 public MeterAsyncQueue() 7 { 8 MeterInfoTask = new MeterInfo(); 9 } 10 11 public MeterInfo MeterInfoTask { get; set; } 12 } 13 public class MeterInfo 14 { 15 public MeterInfo() 16 { 17 18 } 19 public int Id { get; set; } 20 21 }
  1     /// <summary>
  2     /// 線程通用類
  3     /// </summary>
  4     public class TaskCommand
  5     {
  6         CancellationTokenSource tokenSource = new CancellationTokenSource();
  7         ManualResetEvent resetEvent = new ManualResetEvent(true);
  8         Thread thread = null;
  9         /// <summary>
 10         /// 開始任務
 11         /// </summary>
 12         public void StartData()
 13         {
 14             tokenSource = new CancellationTokenSource();
 15             resetEvent = new ManualResetEvent(true);
 16 
 17             List<int> Ids = new List<int>();
 18             for (int i = 0; i < 10000; i++)
 19             {
 20                 Ids.Add(i);
 21             }
 22             thread = new Thread(new ThreadStart(() => StartTask(Ids)));
 23             thread.Start();
 24         }
 25         /// <summary>
 26         /// 暫停任務
 27         /// </summary>
 28         public void OutData()
 29         {
 30             //task暫停
 31             resetEvent.Reset();
 32         }
 33         /// <summary>
 34         /// 繼續任務
 35         /// </summary>
 36         public void ContinueData()
 37         {
 38             //task繼續
 39             resetEvent.Set();
 40         }
 41         /// <summary>
 42         /// 取消任務
 43         /// </summary>
 44         public void Cancel()
 45         {
 46             //釋放對象
 47             resetEvent.Dispose();
 48             foreach (var CurrentTask in ParallelTasks)
 49             {
 50                 if (CurrentTask != null)
 51                 {
 52                     if (CurrentTask.Status == TaskStatus.Running) { }
 53                     {
 54                         //終止task線程
 55                         tokenSource.Cancel();
 56                     }
 57                 }
 58             }
 59             thread.Abort();
 60         }
 61         /// <summary>
 62         /// 執行數據
 63         /// </summary>
 64         /// <param name="Index"></param>
 65         public void Execute(int Index)
 66         {
 67             //阻止當前線程
 68             resetEvent.WaitOne();
 69 
 70             Console.WriteLine("當前第" + Index + "個線程");
 71 
 72             Thread.Sleep(1000);
 73 
 74         }
 75         //隊列對象
 76         private Queue<MeterAsyncQueue> AsyncQueues { get; set; }
 77 
 78         /// <summary>
 79         /// 併發任務數
 80         /// </summary>
 81         private int ParallelTaskCount { get; set; }
 82 
 83 
 84         /// <summary>
 85         /// 並行任務集合
 86         /// </summary>
 87         private List<Task> ParallelTasks { get; set; }
 88         //控制線程並行數量
 89         public void StartTask(List<int> Ids)
 90         {
 91             IsInitTask = true;
 92             ParallelTasks = new List<Task>();
 93             AsyncQueues = new Queue<MeterAsyncQueue>();
 94             //獲取併發數
 95             ParallelTaskCount = 5;
 96 
 97             //初始化非同步隊列
 98             InitAsyncQueue(Ids);
 99             //開始執行隊列任務
100             HandlingTask();
101 
102             Task.WaitAll(new Task[] { Task.WhenAll(ParallelTasks.ToArray()) });
103         }
104         /// <summary>
105         /// 初始化非同步隊列
106         /// </summary>
107         private void InitAsyncQueue(List<int> Ids)
108         {
109             foreach (var item in Ids)
110             {
111                 MeterInfo info = new MeterInfo();
112                 info.Id = item;
113                 AsyncQueues.Enqueue(new MeterAsyncQueue()
114                 {
115                     MeterInfoTask = info
116                 });
117             }
118         }
119         /// <summary>
120         /// 是否首次執行任務
121         /// </summary>
122         private bool IsInitTask { get; set; }
123         //
124         private readonly object _objLock = new object();
125 
126         /// <summary>
127         /// 開始執行隊列任務
128         /// </summary>
129         private void HandlingTask()
130         {
131             lock (_objLock)
132             {
133                 if (AsyncQueues.Count <= 0)
134                 {
135                     return;
136                 }
137 
138                 var loopCount = GetAvailableTaskCount();
139                 //併發處理隊列
140                 for (int i = 0; i < loopCount; i++)
141                 {
142                     HandlingQueue();
143                 }
144                 IsInitTask = false;
145             }
146         }
147         /// <summary>
148         /// 獲取隊列鎖
149         /// </summary>
150         private readonly object _queueLock = new object();
151 
152         /// <summary>
153         /// 處理隊列
154         /// </summary>
155         private void HandlingQueue()
156         {
157             CancellationToken token = tokenSource.Token;
158             lock (_queueLock)
159             {
160                 if (AsyncQueues.Count > 0)
161                 {
162                     var asyncQueue = AsyncQueues.Dequeue();
163 
164                     if (asyncQueue == null) return;
165                     var task = Task.Factory.StartNew(() =>
166                     {
167                         if (token.IsCancellationRequested)
168                         {
169                             return;
170                         }
171                         //阻止當前線程
172                         resetEvent.WaitOne();
173                         //執行任務
174                         Execute(asyncQueue.MeterInfoTask.Id);
175 
176                     }, token).ContinueWith(t =>
177                     {
178                         HandlingTask();
179                     }, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
180                     ParallelTasks.Add(task);
181                 }
182             }
183         }
184         /// <summary>
185         /// 獲取當前有效並行的任務數
186         /// </summary>
187         /// <returns></returns>
188         [MethodImpl(MethodImplOptions.Synchronized)]
189         private int GetAvailableTaskCount()
190         {
191             if (IsInitTask)
192                 return ParallelTaskCount;
193             return 1;
194         }
195     }

 


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

-Advertisement-
Play Games
更多相關文章
  • 來一點咖啡,準備好進入註解的世界。 註解一直是 Java 的一個非常重要的部分,它從 J2SE 5.0 開始就已經存在了。在我們的應用程式代碼中,經常看到 和 這樣的註解。在本文中,我將討論註解到底是什麼,為什麼引入註解,它們是如何工作的,如何編寫自定義註解(有示例代碼),註解的有效場景是什麼,最後 ...
  • 群里看到有人詢問:誰會用python將微信音頻文件尾碼m4a格式轉成mp3格式,毫不猶豫回了句:我會。然後就私下聊起來了 解決方法介紹如下: 工具:windows系統,python2.7,轉換庫ffmpeg 安裝ffmpeg庫:下載對應電腦系統版本 https://ffmpeg.zeranoe.co ...
  • 1. 概覽 在編寫 Spring Boot 應用程式時, "將配置屬性映射到 Java bean 上" 是非常有用的。但是,記錄這些屬性的最好方法是什麼呢? 在本教程中,我們將探討 "Spring Boot Configuration Processor" 和 "關聯的 JSON 元數據文件" ,該 ...
  • 本文導讀: 微服務技術架構選型介紹 k8s 容器化部署架構方案 Eureka 註冊中心問題場景 問題解決手段及原理剖析 閱讀本文建議先瞭解: 1. 註冊中心基本原理 2. K8s(Kuberneters)基本概念 我們的微服務目前都是在伺服器上部署的,也是基於 Docker 來部署的。 運維部門基於 ...
  • Flask中的CBV以及正則表達式 一.CBV 二.正則表達式 ...
  • 一.request 二.response ...
  • .Net Core中間件官網:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0 ASP.Net請求管道: 請求最終會由一個具體的HttpHandler處理(page/as ...
  • 好久沒有寫文章了,最近在用.net core3.0,一些開發中問題順便記錄; 1.首先nuget引入 Autofac Autofac.Extensions.DependencyInjection 2.修改Program.cs 添加.UseServiceProviderFactory(new Auto ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...