C#使用ThreadPool線程池實現採集任務

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections;

namespace 命名空間
{
    public partial class Form1 : Form
    {
        //線程延遲時間
        private int speed = 1000;
        //線程池數量
        private int threadNum = 5;
        //存放未執行的任務
        private ArrayList taskList = new ArrayList();
        //存放已執行的任務
        private List<Object> okTaskList = new List<Object>();
        //是否鎖住任務集合
        private bool look = false;
        public Form1()
        {
            InitializeComponent();
            //解決子線程不能操作UI問題
            CheckForIllegalCrossThreadCalls = false;
            //獲取任務列表
            getTask();
            //創建子線程,執行線程池任務
            new Thread(new ThreadStart(this.PerformTask)) { IsBackground = true }.Start();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //軟件註冊
            RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE", true).CreateSubKey("mySoftWare").CreateSubKey("Register.INI");
            foreach (string str in key.GetSubKeyNames())
            {
                if (str == this.reg.GetRNum())
                {
                    this.Text = "【已註冊】" + this.Text;
                    return;
                }

            }
            this.Text = "【未註冊】" + this.Text;
            base.Hide();
            FrmRegister.state = false;
            //彈出註冊窗口
            FrmRegister register = new FrmRegister();
            register.Disposed += new EventHandler(this.frmRegister_Disposed);
            register.ShowDialog();

        }
        private void frmRegister_Disposed(object sender, EventArgs e)
        {
            base.Close();
        }
        /// <summary>
        /// 線程池任務
        /// </summary>
        private void PerformTask()
        {
            //設置線程池最大線程數量
            ThreadPool.SetMaxThreads(threadNum, threadNum);
            ThreadPool.QueueUserWorkItem(delegate { TaskRun(); });
            //do while循環不能放在這裏,否則會不停的創建線程,使內存爆炸
        }
        /// <summary>
        /// 運行任務的方法
        /// </summary>
        private void TaskRun()
        {
        do{	
            if (taskList != null && taskList.Count > 0 && !look)
            {
                //taskList最大有35個任務,最小0個任務,循環執行
                for (int i = 0; i < taskList.Count; i++)
                {
                    Object key = taskList[i];
                    try
                    {                       
                        //當前任務未執行過,且未被其他線程佔用
                        if (!okTaskList.Contains(key) && Monitor.TryEnter(key, 1000) && !look)
                        {
                            int id = Convert.ToInt32(key);
                            if (id > 0)
                            {
                                /*
                                 * 這裏的業務是訪問接口,獲取想要的數據,然後再顯示數據到UI界面
                                */								
                                //任務執行完添加到已執行的集合裏
                                okTaskList.Add(key);
                                //休眠(線程延遲)
                                Thread.Sleep(this.speed);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.error("執行任務出錯,異常信息:" + ex.Message);
                    }
                    finally
                    {
                        if (Monitor.TryEnter(key))
                        {
                            Monitor.Exit(key);//釋放鎖
                        }
                    }
                }
                //執行完全部任務,就重新記錄
                okTaskList.Clear();
            }
           } while (true);
        }
        /// <summary>
        /// 獲取任務列表
        /// </summary>
        private void getTask()
        {
            //這裏會添加35個任務,從UI界面獲取的,這裏省略
            AddTask(1, "任務名稱");
        }
        /// <summary>
        /// 添加任務
        /// </summary>
        /// <param name="key"></param>
        /// <param name="name"></param>
        private void AddTask(int key, string name)
        {
            //添加好像不需要上鎖,視情況而定,我不加也沒有問題
            //look = true;
            if (!taskList.Contains(key))
            {
                taskList.Add(key);
                //look = false;
            }

        }
        /// <summary>
        ///  /移除任務
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private void RemoveTask(int key)
        {
            look = true;
            for (int i = taskList.Count - 1; i > -1; i--)
            {
                if (key == Convert.ToInt32(taskList[i]))
                {
                    taskList.Remove(taskList[i]);
                    look = false;
                    break;
                }
            }
        }

        //全部開啓和全部關閉的操作
        private void btnAll_Click(object sender, EventArgs e)
        {
            this.labAll.Text = this.btnAll.Checked ? "全部開啓" : "全部關閉";
            handleCheck(this.btnAll.Checked);
            if (this.btnAll.Checked)
            {
                //獲取任務集
                getTask();
            }
            else
            {
                //清空任務集
                taskList.Clear();
            }
        }

        private void handleCheck(bool check)
        {
            this.cheackBox1.Checked = check;
            /*
            * 中間省略,一共35個開關,每個開關控制一個任務對象
            */
            this.cheackBox35.Checked = check;
        }
     
        //開關1的操作,這裏我只列出一個,總共有35個開關
        private void cheackBox1_Click(object sender, EventArgs e)
        {
            if (this.cheackBox1.Checked)
                AddTask(1, "任務1");
            else
                RemoveTask(1);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章