手机
当前位置:查字典教程网 >编程开发 >C#教程 >winform开发使用通用多线程基类分享(以队列形式)
winform开发使用通用多线程基类分享(以队列形式)
摘要:复制代码代码如下://////队列多线程,T代表处理的单个类型~//////publicabstractclassQueueThreadBa...

复制代码 代码如下:

/// <summary>

/// 队列多线程,T 代表处理的单个类型~

/// </summary>

/// <typeparam name="T"></typeparam>

public abstract class QueueThreadBase<T>

{

#region 变量&属性

/// <summary>

/// 待处理结果

/// </summary>

private class PendingResult

{

/// <summary>

/// 待处理值

/// </summary>

public T PendingValue { get; set; }

/// <summary>

/// 是否有值

/// </summary>

public bool IsHad { get; set; }

}

/// <summary>

/// 线程数

/// </summary>

public int ThreadCount

{

get { return this.m_ThreadCount; }

set { this.m_ThreadCount = value; }

}

private int m_ThreadCount = 5;

/// <summary>

/// 取消=True

/// </summary>

public bool Cancel { get; set; }

/// <summary>

/// 线程列表

/// </summary>

List<Thread> m_ThreadList;

/// <summary>

/// 完成队列个数

/// </summary>

private volatile int m_CompletedCount = 0;

/// <summary>

/// 队列总数

/// </summary>

private int m_QueueCount = 0;

/// <summary>

/// 全部完成锁

/// </summary>

private object m_AllCompletedLock = new object();

/// <summary>

/// 完成的线程数

/// </summary>

private int m_CompetedCount = 0;

/// <summary>

/// 队列锁

/// </summary>

private object m_PendingQueueLock = new object();

private Queue<T> m_InnerQueue;

#endregion

#region 事件相关

/// <summary>

/// 全部完成事件

/// </summary>

public event Action<CompetedEventArgs> AllCompleted;

/// <summary>

/// 单个完成事件

/// </summary>

public event Action<T, CompetedEventArgs> OneCompleted;

/// <summary>

/// 引发全部完成事件

/// </summary>

/// <param name="args"></param>

private void OnAllCompleted(CompetedEventArgs args)

{

if (AllCompleted != null)

{

try

{

AllCompleted(args);//全部完成事件

}

catch { }

}

}

/// <summary>

/// 引发单个完成事件

/// </summary>

/// <param name="pendingValue"></param>

/// <param name="args"></param>

private void OnOneCompleted(T pendingValue, CompetedEventArgs args)

{

if (OneCompleted != null)

{

try

{

OneCompleted(pendingValue, args);

}

catch { }

}

}

#endregion

#region 构造

public QueueThreadBase(IEnumerable<T> collection)

{

m_InnerQueue = new Queue<T>(collection);

this.m_QueueCount = m_InnerQueue.Count;

}

#endregion

#region 主体

/// <summary>

/// 初始化线程

/// </summary>

private void InitThread()

{

m_ThreadList = new List<Thread>();

for (int i = 0; i < ThreadCount; i++)

{

Thread t = new Thread(new ThreadStart(InnerDoWork));

m_ThreadList.Add(t);

t.IsBackground = true;

t.Start();

}

}

/// <summary>

/// 开始

/// </summary>

public void Start()

{

InitThread();

}

/// <summary>

/// 线程工作

/// </summary>

private void InnerDoWork()

{

try

{

Exception doWorkEx = null;

DoWorkResult doworkResult = DoWorkResult.ContinueThread;

var t = CurrentPendingQueue;

while (!this.Cancel && t.IsHad)

{

try

{

doworkResult = DoWork(t.PendingValue);

}

catch (Exception ex)

{

doWorkEx = ex;

}

m_CompletedCount++;

int precent = m_CompletedCount * 100 / m_QueueCount;

OnOneCompleted(t.PendingValue, new CompetedEventArgs() { CompetedPrecent = precent, InnerException = doWorkEx });

if (doworkResult == DoWorkResult.AbortAllThread)

{

this.Cancel = true;

break;

}

else if (doworkResult == DoWorkResult.AbortCurrentThread)

{

break;

}

t = CurrentPendingQueue;

}

lock (m_AllCompletedLock)

{

m_CompetedCount++;

if (m_CompetedCount == m_ThreadList.Count)

{

OnAllCompleted(new CompetedEventArgs() { CompetedPrecent = 100 });

}

}

}

catch

{

throw;

}

}

/// <summary>

/// 子类重写

/// </summary>

/// <param name="pendingValue"></param>

/// <returns></returns>

protected virtual DoWorkResult DoWork(T pendingValue)

{

return DoWorkResult.ContinueThread;

}

/// <summary>

/// 获取当前结果

/// </summary>

private PendingResult CurrentPendingQueue

{

get

{

lock (m_PendingQueueLock)

{

PendingResult t = new PendingResult();

if (m_InnerQueue.Count != 0)

{

t.PendingValue = m_InnerQueue.Dequeue();

t.IsHad = true;

}

else

{

t.PendingValue = default(T);

t.IsHad = false;

}

return t;

}

}

}

#endregion

#region 相关类&枚举

/// <summary>

/// dowork结果枚举

/// </summary>

public enum DoWorkResult

{

/// <summary>

/// 继续运行,默认

/// </summary>

ContinueThread = 0,

/// <summary>

/// 终止当前线程

/// </summary>

AbortCurrentThread = 1,

/// <summary>

/// 终止全部线程

/// </summary>

AbortAllThread = 2

}

/// <summary>

/// 完成事件数据

/// </summary>

public class CompetedEventArgs : EventArgs

{

public CompetedEventArgs()

{

}

/// <summary>

/// 完成百分率

/// </summary>

public int CompetedPrecent { get; set; }

/// <summary>

/// 异常信息

/// </summary>

public Exception InnerException { get; set; }

}

#endregion

}

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

}

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

复制代码 代码如下:

/// <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);

}

}

用法

总结:

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

【winform开发使用通用多线程基类分享(以队列形式)】相关文章:

基于一个应用程序多线程误用的分析详解

获取wince mac地址与IP地址解决方案

c# 对windows用户和组操作实例

c# winform多线程的小例子

c#开发的程序安装时动态指定windows服务名称

C#基础继承和多态详解

C# 多态性的深入理解

.Net WInform开发笔记(五)关于事件Event

用 C# Winform做出全透明的磨砂玻璃窗体效果代码

解析美国东部时间与北京时间相互转换的实现代码

精品推荐
分类导航