个人原创、欢迎转载、转载请注明出处、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
 

c#通用多线程基类,以队列形式的更多相关文章

  1. C++虚基类详解(转)

    我们知道,如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员.在引用这些同名的成员时,必须在派生类对象名后增加直接基类名,以避 ...

  2. 本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善(转)

    本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善 namespace Web.Mvc.Extensions { #region 验证基类 /// <summary ...

  3. Java如何解决脆弱基类(基类被冻结)问题

    概述  大多数好的设计者象躲避瘟疫一样来避免使用实现继承(extends 关系).实际上80%的代码应该完全用interfaces写,而不是通过extends.“JAVA设计模式”一书详细阐述了怎样用 ...

  4. C# 通用数据访问类(SqlHelper)

    [转]C# 通用数据访问类(SqlHelper) 注:本文转自http://www.tzwhx.com/newOperate/html/3/31/312/13080.htmlVisual C# 动态操 ...

  5. iOS多线程常用类说明--备用参考

    iOS的多线程,涉及到如下一些类,这里集中做个介绍,免得混淆. 1.NSTimer 很显然,这是定时器类 2.NSTask iOS 不支持 NSTask 在很多并发操作的时候,多线程太耗资源,也太危险 ...

  6. C++:抽象基类和纯虚函数的理解

    转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...

  7. iOS多线程常用类说明

    iOS的多线程,涉及到如下一些类,这里集中做个介绍,免得混淆. 1.NSTimer 很显然,这是定时器类 2.NSTask iOS 不支持 NSTask 在很多并发操作的时候,多线程太耗资源,也太危险 ...

  8. NSObject class和NSObject protocol的关系(抽象基类与协议)

    [转载请注明出处] 1.接口的实现 对于接口这一概念的支持,不同语言的实现形式不同.Java中,由于不支持多重继承,因此提供了一个Interface关键词.而在C++中,通常是通过定义抽象基类的方式来 ...

  9. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

随机推荐

  1. 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能

    一.搭建開始前的准备 1.我用的MyEclipse2014版,大家也能够用IDEA. 2.下载Tomcat(免安装解压包).MySQL(zip包下载地址 免安装解压包,优点就是双击启动,最后我会把ba ...

  2. 向西项目管理工具Maven一片

    前言 相信仅仅要做过 Java 开发的童鞋们,对 Ant 想必都不陌生,我们往往使用 Ant 来构建项目,尤其是涉及到特别繁杂的工作量.一个 build.xml 可以完毕编译.測试.打包.部署等非常多 ...

  3. java字节中的基本类型的职业的数目 (采访总是问)

    因为移动装置存储器中的移动开发的局限性,数据的字节数需要考虑往往在占领中使用的类型. 下面介绍下一个Java,以加深记忆. 在Java中一共同拥有8种基本数据类型,当中有4种整型,2种浮点类型,1种用 ...

  4. KafkaOffsetMonitor

    Kafka实战-KafkaOffsetMonitor   1.概述 前面给大家介绍了Kafka的背景以及一些应用场景,并附带上演示了Kafka的简单示例.然后,在开发的过程当中,我们会发现一些问题,那 ...

  5. suggest的使用方法

    suggest的使用方法注意: 1. 要表示汉语的"建议做某事",英语通经常使用suggest doing sth,而不能用 suggest to do sth: 2. " ...

  6. do...while(0)神奇

    1. do...while(0)消除goto语句. 通常,假设在一个函数中開始要分配一些资源.然后在中途运行过程中假设遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样: version ...

  7. springmvc4

    web项目(使用html视图解析器)   完整配置springmvc4,最终视图选择的是html,非静态文件. 最近自己配置spring的时候,遇到很多问题,由于开发环境和版本的变化导致网友们给出的建 ...

  8. 离github在导入dubbo工程

    dubbo移动到github目前已经有一些时间,我们可能根本不习惯使用github.因此,我们仍然使用以前的版本号. 由于某些原因.阿里下载前关闭.在这里给大家提供一个私有地址: 链接:http:// ...

  9. 完整详细的说明GCD列(一)dispatch_async;dispatch_sync;dispatch_async_f;dispatch_sync_f

    为什么要写这个系列,由于百度了一下.我们正在寻找一个非常比较片面的Blog.抄来抄去,写作是很粗糙. 所以,我想写这个系列,尝试记录官方网站GCD强大的全功能的表达.为了方便他们,也方便他人,假设有发 ...

  10. LeetCode:same_tree题解

    一.     题目: 给定两个二叉树,编写一个函数来检查它们是否相等或为空树.假设两个二叉树被觉得是相等的,那么它们在结构上是同样的,而且随意节点具有同样的值. 二.     分析 非常easy的题目 ...