#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.从构造函数来看,处理的是一个确定的列表.没错.这个多线程只能处理已经确定的列表,你是否会问.可不可以一边添加,一边处理呢?(呵呵,可以,请联系楼主,当然你也可以自己写,是吧?!)
2.提供撤销的功能
3.提供线程个数修改功能
4.提供多种事件响应,如单个完成,全部完成的事件
5.提供完成的百分率
}
/// <summary>
/// 完成百分率
/// </summary>
public int competedprecent { get; set; }
/// <summary>
/// 异常信息
/// </summary>
public exception innerexception { get; set; }
}
6.提供终止线程的方式,继续/单线程终止/全部终止
你是否会问?怎么用呢?别急....请看
}
/// <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);
}
}
用法
总结:
多线程在什么时候都会用到.不用到是你不会用.多线程要一定的编程基础,如果你觉得有点难度,那你可以学习并且借鉴人家已有的东西.少走弯路,是我们程序员经历嗷嗷待哺后的心声.本文以交流态度和感恩心态,贡献给有需要的人们.
如对本文有疑问, 点击进行留言回复!!
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
C#实现获取本地内网(局域网)和外网(公网)IP地址的方法分析
网友评论