欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

winform开发使用通用多线程基类分享(以队列形式)

程序员文章站 2024-02-23 19:17:58
  复制代码 代码如下:///     /// 队列多线程,t 代表处理的单个类型~ &n...

 

复制代码 代码如下:

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

用法

总结:

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