多线程处理器 适用于 已知要处理任务的个数,进行多线程处理

核心的类代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Threading;

namespace DPC.CaptureImages
{
    public delegate void TaskExecutingHandler(object sender, object taskData);

    public delegate void TaskFinishedHandler(object sender, bool hasError);

    /// <summary>
    /// 多线程任务执行器
    /// </summary>
    public class MultiThreadExecuter
    {
        /// <summary>
        /// 最大线程数
        /// </summary>
        private int m_MaxThreadCount;
        /// <summary>
        /// 有错误发生时,是否停止所有任务执行
        /// </summary>
        private bool m_StopWhenOnError;

        private ArrayList m_TaskList = new ArrayList();
        private Thread[] m_ThreadList;
        private ParameterizedThreadStart m_ExecuteMethod;
        /// <summary>
        /// 当前完成任务数
        /// </summary>
        private int CurrentFinishCount = 0;

        private Exception m_AbortException = null;
        /// <summary>
        /// 获取导致任务终止的异常
        /// </summary>
        public Exception AbortException
        {
            get { return m_AbortException; }
        }
        /// <summary>
        /// 总任务数
        /// </summary>
        public int TaskCount
        {
            get { return m_TaskList.Count; }
        }

        /// <summary>
        /// 一个任务开始执行前发生
        /// </summary>
        public event TaskExecutingHandler OneStarting;
        /// <summary>
        /// 一个任务成功执行完成
        /// </summary>
        public event TaskExecutingHandler OneFinished;
        /// <summary>
        /// 所有任务执行完成
        /// </summary>
        public event TaskFinishedHandler AllFinished; 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxThreadCount">最大线程数</param>
        /// <param name="stopWhenOnError">为True时,发生错误后停止任务执行,否则继续任务其余任务</param>
        /// <param name="executeMethod">任务执行方法委托</param>
        public MultiThreadExecuter(ParameterizedThreadStart executeMethod, int maxThreadCount, bool stopWhenOnError)
        {
            if (executeMethod == null)
                throw new ArgumentNullException("executeMethod");

            if (maxThreadCount < 1 || maxThreadCount > 20)
                throw new ArgumentException("最大线程数必须为1到20之间的数", "maxThreadCount");

            m_ExecuteMethod = executeMethod;
            m_MaxThreadCount = maxThreadCount;
            m_StopWhenOnError = stopWhenOnError;
        }

        /// <summary>
        /// 开始执行多线程任务
        /// </summary>
        public void Start()
        {
            if (m_ThreadList == null)
            {
                if (m_TaskList.Count > m_MaxThreadCount)
                    m_ThreadList = new Thread[m_MaxThreadCount];
                else
                    m_ThreadList = new Thread[m_TaskList.Count];

                for (int i = 0; i < m_ThreadList.Length; i++)
                {
                    m_ThreadList[i] = new Thread(new ParameterizedThreadStart(ThreadProc));
                }
            }

            CurrentFinishCount = 0;
            m_PostFinishEventOnce = false;
            m_Terminated = false;
            for (int i = 0; i < m_ThreadList.Length; i++)
            {
                m_ThreadList[i].Start(i);
            }
        }
        /// <summary>
        /// 是否已经触发了一次完成事件AllFinished
        /// </summary>
        private bool m_PostFinishEventOnce = false;
        /// <summary>
        /// 是否正在终止任务执行
        /// </summary>
        private bool m_Terminated = false;

        private void ThreadProc(object obj)
        {
            int index = (int)obj;
            while (index < m_TaskList.Count)
            {
                if (m_Terminated) return;
                try
                {
                    //通知一个任务开始
                    if (OneStarting != null && !m_Terminated)
                        OneStarting(this, m_TaskList[index]);

                    m_ExecuteMethod(m_TaskList[index]);

                    //通知一个任务结束
                    if (OneFinished != null && !m_Terminated)
                        OneFinished(this, m_TaskList[index]);
                }
                catch(Exception ex)
                {
                    m_AbortException = ex;
                    if (m_StopWhenOnError)
                    {
                        if (m_PostFinishEventOnce == false)
                        {
                            lock (this)
                            {
                                if (m_PostFinishEventOnce == false)
                                {
                                    m_PostFinishEventOnce = true;
                                    if (AllFinished != null)
                                        AllFinished(this, true);
                                }
                            }                            
                        }
                        this.Stop();
                        return;
                    }
                }
                index += m_ThreadList.Length;
                lock (this)
                {
                    CurrentFinishCount++;
                }
            }
            if (CurrentFinishCount == m_TaskList.Count)
            {
                if (AllFinished != null)
                    AllFinished(this, false);
            }
        }
        /// <summary>
        /// 暂停任务执行
        /// </summary>
        public void Pause()
        {
            foreach (Thread thread in m_ThreadList)
            {
                thread.Suspend();
            }
        }
        /// <summary>
        /// 继续执行暂停任务
        /// </summary>
        public void Continue()
        {
            foreach (Thread thread in m_ThreadList)
            {
                thread.Resume();
            }
        }

        /// <summary>
        /// 停止执行任务
        /// </summary>
        public void Stop()
        {
            lock (this)
            {
                m_Terminated = true;
            }   
        }
        /// <summary>
        /// 终止所有执行任务线程
        /// </summary>
        public void Abort()
        {
            foreach (Thread thread in m_ThreadList)
            {
                if (Thread.CurrentThread.ManagedThreadId != thread.ManagedThreadId)
                {
                    thread.Abort();
                }
            }
        }

        /// <summary>
        /// 等待所有任务执行完成
        /// </summary>
        /// <returns></returns>
        public void WaitFinish()
        {
            foreach (Thread thread in m_ThreadList)
            {
                thread.Join(5000);
            }
        }

        /// <summary>
        /// 添加一个任务项
        /// </summary>
        /// <param name="taskData"></param>
        public void AddTask(object taskData)
        {
            m_TaskList.Add(taskData);
        }

        
    }
}
View Code

 

进度条窗体类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DMLib;

namespace DPC.CaptureImages
{
    public partial class ProgressBarForm : Form
    {
        public ProgressBarForm(MultiThreadExecuter executer)
        {
            if (executer == null)
                throw new ArgumentNullException("executer");
            m_Executer = executer;

            InitializeComponent();
        }

        private bool m_CanClose = false;
        private MultiThreadExecuter m_Executer = null;

        private void ProgressBarForm_Shown(object sender, EventArgs e)
        {
            //m_Executer.OneStarting += new TaskExecutingHandler(m_Executer_OneStarting);
            m_Executer.OneFinished += new TaskExecutingHandler(m_Executer_OneFinished);
            m_Executer.AllFinished += new TaskFinishedHandler(m_Executer_AllFinished);

            progressBar1.Maximum = m_Executer.TaskCount * 10;
            progressBar1.Minimum = 0;
            progressBar1.Step = 10;
            progressBar1.Value = 0;

            m_Executer.Start();
        }

        void m_Executer_AllFinished(object sender, bool hasError)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new TaskFinishedHandler(this.m_Executer_AllFinished), sender, hasError);
                return;
            }

            m_CanClose = true;

            if (hasError)
            {
                Logging.LoggingError(m_Executer.AbortException);
                MessageBoxHelper.ShowErrorMessage(m_Executer.AbortException.Message);
                this.DialogResult = DialogResult.Cancel;
                this.Close();
                return;
            }

            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        void m_Executer_OneFinished(object sender, object taskData)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new TaskExecutingHandler(this.m_Executer_OneFinished), sender, taskData);
                return;
            }

            progressBar1.PerformStep();
        }

        void m_Executer_OneStarting(object sender, object taskData)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new TaskExecutingHandler(this.m_Executer_OneStarting), sender, taskData);
                return;
            }

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            btnCancel.Enabled = false;
            m_Executer.Stop();
            m_Executer.WaitFinish();
            m_CanClose = true;
            this.Close();
        }

        private void ProgressBarForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.m_CanClose)
                e.Cancel = true;

            if (e.CloseReason != CloseReason.UserClosing)
                e.Cancel = false;

        }



    }
}
View Code

 

转载于:https://www.cnblogs.com/baihong/p/9233602.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值