zoukankan      html  css  js  c++  java
  • c#通用多线程基类,以队列形式

    个人原创、欢迎转载、转载请注明出处、http://www.cnblogs.com/zetee/p/3487084.html

      多线程这个概念大家都很熟悉,对于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     }
    复制代码

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

    public QueueThreadBase(IEnumerable<T> collection)

      2.提供撤销的功能

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

      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
            }
    复制代码

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

    复制代码
     1     /// <summary>
     2     /// 下载线程对了.
     3     /// </summary>
     4     public class DownLoadQueueThread:QueueThreadBase<int>
     5     {
     6         /// <summary>
     7         /// 
     8         /// </summary>
     9         /// <param name="list">下载的列表ID</param>
    10         public DownLoadQueueThread(IEnumerable<int> list):base(list)
    11         {
    12 
    13         }
    14         /// <summary>
    15         /// 每次多线程都到这里来,处理多线程
    16         /// </summary>
    17         /// <param name="pendingValue"列表ID></param>
    18         /// <returns></returns>
    19         protected override DoWorkResult DoWork(int pendingID)
    20         {
    21             try
    22             {
    23 
    24                 //..........多线程处理....
    25                 return DoWorkResult.ContinueThread;//没有异常让线程继续跑..
    26 
    27             }
    28             catch (Exception)
    29             {
    30 
    31                 return DoWorkResult.AbortCurrentThread;//有异常,可以终止当前线程.当然.也可以继续,
    32                 //return  DoWorkResult.AbortAllThread; //特殊情况下 ,有异常终止所有的线程...
    33             }
    34 
    35             //return base.DoWork(pendingValue);
    36         }
    37     }
    复制代码

      总结:

      多线程在什么时候都会用到.不用到是你不会用.多线程要一定的编程基础,如果你觉得有点难度,那你可以学习并且借鉴人家已有的东西.少走弯路,是我们程序员经历嗷嗷待哺后的心声.本文以交流态度和感恩心态,贡献给有需要的人们.

     
     
     
    标签: 多线程.net
     
  • 相关阅读:
    LeetCode解题报告—— Permutations & Permutations II & Rotate Image
    LeetCode解题报告—— Combination Sum & Combination Sum II & Multiply Strings
    LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
    顺利通过EMC试验(2)
    CSS复合选择器
    Emmet快速生成HTML和CSS
    Spring 三种创建Bean的方式
    Spring BeanFactory和ApplicationContext的区别
    Spring ApplicationContext的三个实现类详解
    CSS的引入方式
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3489538.html
Copyright © 2011-2022 走看看