c#通用多线程基类,以队列形式

 多线程这个概念大家都很熟悉,对于winform的开发人员来说.用的还是多的.但估计都是用Timer,或者backgroundWorker.

  你是否曾经想过,写一个基类,然后....一用到多线程的时候,就马上能用上呢.

没错,福利来了,这面我为大家写了多线程的一个基类.只有你用到多线程,下面的代码肯定能帮到你很多忙 

  1 /// <summary>
  2     /// 队列多线程,T 代表处理的单个类型~
  3     /// </summary>
  4     /// <typeparam name="T"></typeparam>
  5     public abstract class QueueThreadBase<T>
  6     {
  7         #region 变量&属性
  8         /// <summary>
  9         /// 待处理结果
 10         /// </summary>
 11         private class PendingResult
 12         {
 13             /// <summary>
 14             /// 待处理值
 15             /// </summary>
 16             public T PendingValue { get; set; }
 17             /// <summary>
 18             /// 是否有值
 19             /// </summary>
 20             public bool IsHad { get; set; }
 21         }
 22         /// <summary>
 23         /// 线程数
 24         /// </summary>
 25         public int ThreadCount
 26         {
 27             get { return this.m_ThreadCount; }
 28             set { this.m_ThreadCount = value; }
 29         }
 30         private int m_ThreadCount = 5;
 31         /// <summary>
 32         /// 取消=True
 33         /// </summary>
 34         public bool Cancel { get; set; }
 35         /// <summary>
 36         /// 线程列表
 37         /// </summary>
 38         List<Thread> m_ThreadList;
 39         /// <summary>
 40         /// 完成队列个数
 41         /// </summary>
 42         private volatile int m_CompletedCount = 0;
 43         /// <summary>
 44         /// 队列总数
 45         /// </summary>
 46         private int m_QueueCount = 0;
 47         /// <summary>
 48         /// 全部完成锁
 49         /// </summary>
 50         private object m_AllCompletedLock = new object();
 51         /// <summary>
 52         /// 完成的线程数
 53         /// </summary>
 54         private int m_CompetedCount = 0;
 55         /// <summary>
 56         /// 队列锁
 57         /// </summary>
 58         private object m_PendingQueueLock = new object();
 59         private Queue<T> m_InnerQueue;
 60         #endregion
 61 
 62 
 63         #region 事件相关
 64         /// <summary>
 65         /// 全部完成事件
 66         /// </summary>
 67         public event Action<CompetedEventArgs> AllCompleted;
 68         /// <summary>
 69         /// 单个完成事件
 70         /// </summary>
 71         public event Action<T, CompetedEventArgs> OneCompleted;
 72         /// <summary>
 73         /// 引发全部完成事件
 74         /// </summary>
 75         /// <param name="args"></param>
 76         private void OnAllCompleted(CompetedEventArgs args)
 77         {
 78             if (AllCompleted != null)
 79             {
 80                 try
 81                 {
 82                     AllCompleted(args);//全部完成事件
 83                 }
 84                 catch { }
 85             }
 86         }
 87         /// <summary>
 88         /// 引发单个完成事件
 89         /// </summary>
 90         /// <param name="pendingValue"></param>
 91         /// <param name="args"></param>
 92         private void OnOneCompleted(T pendingValue, CompetedEventArgs args)
 93         {
 94             if (OneCompleted != null)
 95             {
 96                 try
 97                 {
 98                     OneCompleted(pendingValue, args);
 99                 }
100                 catch { }
101 
102             }
103         } 
104         #endregion
105 
106         #region 构造
107         public QueueThreadBase(IEnumerable<T> collection)
108         {
109             m_InnerQueue = new Queue<T>(collection);
110             this.m_QueueCount = m_InnerQueue.Count;
111         }
112         
113         #endregion
114 
115         #region 主体
116         /// <summary>
117         /// 初始化线程
118         /// </summary>
119         private void InitThread()
120         {
121             m_ThreadList = new List<Thread>();
122             for (int i = 0; i < ThreadCount; i++)
123             {
124                 Thread t = new Thread(new ThreadStart(InnerDoWork));
125         m_ThreadList.Add(t);
126                 t.IsBackground = true;
127                 t.Start();
128             }
129         }
130         /// <summary>
131         /// 开始
132         /// </summary>
133         public void Start()
134         {
135             InitThread();
136         }
137         /// <summary>
138         /// 线程工作
139         /// </summary>
140         private void InnerDoWork()
141         {
142             try
143             {
144                 Exception doWorkEx = null;
145                 DoWorkResult doworkResult = DoWorkResult.ContinueThread;
146                 var t = CurrentPendingQueue;
147                 while (!this.Cancel && t.IsHad)
148                 {
149                     try
150                     {
151                         doworkResult = DoWork(t.PendingValue);
152                     }
153                     catch (Exception ex)
154                     {
155                         doWorkEx = ex;
156                     }
157                     m_CompletedCount++;
158                     int precent = m_CompletedCount * 100 / m_QueueCount;
159                     OnOneCompleted(t.PendingValue, new CompetedEventArgs() { CompetedPrecent = precent, InnerException = doWorkEx });
160                     if (doworkResult == DoWorkResult.AbortAllThread)
161                     {
162                         this.Cancel = true;
163                         break;
164                     }
165                     else if (doworkResult == DoWorkResult.AbortCurrentThread)
166                     {
167                         break;
168                     }
169                     t = CurrentPendingQueue;
170                 }
171 
172                 lock (m_AllCompletedLock)
173                 {
174                     m_CompetedCount++;
175                     if (m_CompetedCount == m_ThreadList.Count)
176                     {
177                         OnAllCompleted(new CompetedEventArgs() { CompetedPrecent = 100 });
178                     }
179                 }
180 
181             }
182             catch 
183             {
184                 throw;
185             }
186         }
187         /// <summary>
188         /// 子类重写
189         /// </summary>
190         /// <param name="pendingValue"></param>
191         /// <returns></returns>
192         protected virtual DoWorkResult DoWork(T pendingValue)
193         {
194             return DoWorkResult.ContinueThread;
195         }
196         /// <summary>
197         /// 获取当前结果
198         /// </summary>
199         private PendingResult CurrentPendingQueue
200         {
201             get
202             {
203                 lock (m_PendingQueueLock)
204                 {
205                     PendingResult t = new PendingResult();
206                     if (m_InnerQueue.Count != 0)
207                     {
208                         t.PendingValue = m_InnerQueue.Dequeue();
209                         t.IsHad = true;
210                     }
211                     else
212                     {
213                         t.PendingValue = default(T);
214                         t.IsHad = false;
215                     }
216                     return t;
217                 }
218             }
219         }
220          
221         #endregion
222 
223         #region 相关类&枚举
224         /// <summary>
225         /// dowork结果枚举
226         /// </summary>
227         public enum DoWorkResult
228         {
229             /// <summary>
230             /// 继续运行,默认
231             /// </summary>
232             ContinueThread = 0,
233             /// <summary>
234             /// 终止当前线程
235             /// </summary>
236             AbortCurrentThread = 1,
237             /// <summary>
238             /// 终止全部线程
239             /// </summary>
240             AbortAllThread = 2
241         }
242         /// <summary>
243         /// 完成事件数据
244         /// </summary>
245         public class CompetedEventArgs : EventArgs
246         {
247             public CompetedEventArgs()
248             {
249 
250             }
251             /// <summary>
252             /// 完成百分率
253             /// </summary>
254             public int CompetedPrecent { get; set; }
255             /// <summary>
256             /// 异常信息
257             /// </summary>
258             public Exception InnerException { get; set; }
259         } 
260         #endregion
261 
262     }
View Code

1.从构造函数来看,处理的是一个确定的列表.没错.这个多线程只能处理已经确定的列表,你是否会问.可不可以一边添加,一边处理呢?(呵呵,可以,请联系楼主,当然你也可以自己写,是吧?!)

1 public QueueThreadBase(IEnumerable<T> collection)

2.提供撤销的功能

/// <summary>
        /// 取消=True
        /// </summary>
        public bool Cancel { get; set; }
View Code

3.提供线程个数修改功能

    /// <summary>
        /// 线程数
        /// </summary>
        public int ThreadCount
        {
            get { return this.m_ThreadCount; }
            set { this.m_ThreadCount = value; }
        }

4.提供多种事件响应,如单个完成,全部完成的事件

/// <summary>
        /// 全部完成事件
        /// </summary>
        public event Action<CompetedEventArgs> AllCompleted;
        /// <summary>
        /// 单个完成事件
        /// </summary>
        public event Action<T, CompetedEventArgs> OneCompleted;

5.提供完成的百分率

        /// <summary>
        /// 完成事件数据
        /// </summary>
        public class CompetedEventArgs : EventArgs
        {
            public CompetedEventArgs()
            {

            }
            /// <summary>
            /// 完成百分率
            /// </summary>
            public int CompetedPrecent { get; set; }
            /// <summary>
            /// 异常信息
            /// </summary>
            public Exception InnerException { get; set; }
        } 

6.提供终止线程的方式,继续/单线程终止/全部终止

        /// <summary>
        /// dowork结果枚举
        /// </summary>
        public enum DoWorkResult
        {
            /// <summary>
            /// 继续运行,默认
            /// </summary>
            ContinueThread = 0,
            /// <summary>
            /// 终止当前线程
            /// </summary>
            AbortCurrentThread = 1,
            /// <summary>
            /// 终止全部线程
            /// </summary>
            AbortAllThread = 2
        }

你是否会问?怎么用呢?别急....请看 

/// <summary>
    /// 下载线程对了.
    /// </summary>
    public class DownLoadQueueThread:QueueThreadBase<int>
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="list">下载的列表ID</param>
        public DownLoadQueueThread(IEnumerable<int> list):base(list)
        {

        }
        /// <summary>
        /// 每次多线程都到这里来,处理多线程
        /// </summary>
        /// <param name="pendingValue"列表ID></param>
        /// <returns></returns>
        protected override DoWorkResult DoWork(int pendingID)
        {
            try
            {

                //..........多线程处理....
                return DoWorkResult.ContinueThread;//没有异常让线程继续跑..

            }
            catch (Exception)
            {

                return DoWorkResult.AbortCurrentThread;//有异常,可以终止当前线程.当然.也可以继续,
                //return  DoWorkResult.AbortAllThread; //特殊情况下 ,有异常终止所有的线程...
            }

            //return base.DoWork(pendingValue);
        }
    }

用法
View Code

 

转载于:https://www.cnblogs.com/test404/p/6698687.html

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值