Winform线程队列的使用,模拟下载等待功能

来源:互联网 发布:剑三雪河炮太捏脸数据 编辑:程序博客网 时间:2024/06/16 04:34


using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace QueueWinForm{    public partial class Form1 : Form    {        //***********************************************************************************        //此内容涉及的知识点有:“线程Thread”“异步BeginInvoke”“锁Lock”“信号量Semphore”        //“Lambda表达式”“队列Queue<T>”“任务Task”“LinQ查询”        //***********************************************************************************        #region 参数        /// <summary>        /// 锁        /// </summary>        private object locker = new object();        /// <summary>        /// 队列数据        /// </summary>        private Queue<FileText> _FileQueue = new Queue<FileText>();        /// <summary>        /// 信号量        /// </summary>        private Semaphore LimitSemaphore = null;        /// <summary>        /// 保存文件        /// </summary>        private List<FileText> _FileList = new List<FileText>();        #endregion        #region 构造函数        public Form1()        {            InitializeComponent();            this.Load += (sender, e) =>            {                InitSemphore();//信号量实例化                StartDequeueTask();//程序启动就预先执行出队列任务                RandomFile();//程序启动就预先执行随机文件操作,模拟文件并发现象            };        }        #endregion        #region 随机文件线程        /// <summary>        /// 随机文件        /// </summary>        private void RandomFile()        {            new Thread(() => {                while (true)                {                    lock (this)                    {                        if (_FileList.Count > 0)                        {                            int random = new Random().Next(_FileList.Count);                            FileText ft = _FileList[random];                            DequeueTask(ft);                        }                        else                            Thread.Sleep(20);                    }                }            }) { IsBackground = true }.Start();         }        /// <summary>        /// 初始化信号量        /// </summary>        private void InitSemphore()        {            int result = 0;            bool isInt = int.TryParse(tbThreadNum.Text, out result);            if (isInt)                LimitSemaphore = new Semaphore(result, 6);            else                LimitSemaphore = new Semaphore(0, 1);        }        #endregion        #region 文件出队列        /// <summary>        /// 判断队列中是否还有文件数据        /// </summary>        private bool isHavedFileData        {            get             {                return _FileQueue.Count > 0;            }        }        /// <summary>        /// 执行出队列任务        /// </summary>        private void StartDequeueTask()        {            Task.Factory.StartNew(() =>            {                while (true)                {                    FileText ft = DequeueFile();                    if (ft != null || _FileQueue.Count > 0)                    {                        DequeueTask(ft);                    }                    else                        Thread.Sleep(20);                }            });        }        /// <summary>        /// 队列任务进行中        /// </summary>        /// <param name="ft"></param>        private void DequeueTask(FileText ft)        {            if (ft != null)            {                switch (ft.pbName)                {                    case "taskPro1":                        var file1 = from f in _FileList                                    where f.pbName == "taskPro1"                                    select f;                        int count1 = ft.startPro;                        int max1 = ft.endPro;                        if (count1 < max1)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                                {                                    Console.WriteLine(count1);                                    taskPro1.Maximum = max1;                                    taskPro1.Value = count1;                                    if (taskPro1.Value != 0)                                        lbPro1.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro1.Maximum * count1));                                }));                                count1++;                                foreach (var item in file1)                                {                                    item.startPro = count1;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro1"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask1,true);                            }                        }                        break;                    case "taskPro2":                        var file2 = from f in _FileList                                    where f.pbName == "taskPro2"                                    select f;                        int count2 = ft.startPro;                        int max2 = ft.endPro;                        if (count2 < max2)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                                {                                    taskPro2.Maximum = max2;                                    taskPro2.Value = count2;                                    if (taskPro2.Value != 0)                                        lbPro2.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro2.Maximum * count2));                                }));                                count2++;                                foreach (var item in file2)                                {                                    item.startPro = count2;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro2"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask2, true);                            }                        }                        break;                    case "taskPro3":                        var file3 = from f in _FileList                                    where f.pbName == "taskPro3"                                    select f;                        int count3 = ft.startPro;                        int max3 = ft.endPro;                        if (count3 < max3)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                               {                                   taskPro3.Maximum = max3;                                   taskPro3.Value = count3;                                   if (taskPro3.Value != 0)                                       lbPro3.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro3.Maximum * count3));                               }));                                count3++;                                foreach (var item in file3)                                {                                    item.startPro = count3;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro3"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask3, true);                            }                        }                        break;                    case "taskPro4":                        var file4 = from f in _FileList                                    where f.pbName == "taskPro4"                                    select f;                        int count4 = ft.startPro;                        int max4 = ft.endPro;                        if (count4 < max4)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                               {                                   taskPro4.Maximum = max4;                                   taskPro4.Value = count4;                                   if (taskPro4.Value != 0)                                       lbPro4.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro4.Maximum * count4));                               }));                                count4++;                                foreach (var item in file4)                                {                                    item.startPro = count4;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro4"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask4, true);                            }                        }                        break;                    case "taskPro5":                        var file5 = from f in _FileList                                    where f.pbName == "taskPro5"                                    select f;                        int count5 = ft.startPro;                        int max5 = ft.endPro;                        if (count5 < max5)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                               {                                   taskPro5.Maximum = max5;                                   taskPro5.Value = count5;                                   if (taskPro5.Value != 0)                                       lbPro5.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro5.Maximum * count5));                               }));                                count5++;                                foreach (var item in file5)                                {                                    item.startPro = count5;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro5"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask5, true);                            }                        }                        break;                    case "taskPro6":                        var file6 = from f in _FileList                                    where f.pbName == "taskPro6"                                    select f;                        int count6 = ft.startPro;                        int max6 = ft.endPro;                        if (count6 < max6)                        {                            try                            {                                this.BeginInvoke(new MethodInvoker(() =>                               {                                   taskPro6.Maximum = max6;                                   taskPro6.Value = count6;                                   if (taskPro6.Value != 0)                                       lbPro6.Text = string.Format("{0}%", Math.Truncate(100 / (double)taskPro6.Maximum * count6));                               }));                                count6++;                                foreach (var item in file6)                                {                                    item.startPro = count6;                                }                                Thread.Sleep(1);                            }                            catch { }                        }                        else                        {                            lock (this)                            {                                FileText fText = _FileList.Find(r => r.pbName.Equals("taskPro6"));                                if (fText != null)                                {                                    _FileList.Remove(fText);                                    LimitSemaphore.Release();                                }                                isEnable(btnTask6, true);                            }                        }                        break;                    default:                        break;                }            }        }        /// <summary>        /// 出队列        /// </summary>        private FileText DequeueFile()        {            FileText ft = null;            lock (locker)            {                if (isHavedFileData)                {                    ft = _FileQueue.Dequeue();                }            }            return ft;        }        #endregion        #region 文件进队列        /// <summary>        /// 文件进队列        /// </summary>        /// <param name="ft"></param>        private void EnqueueFile(FileText ft)        {            lock (locker)            {                _FileQueue.Enqueue(ft);                _FileList.Add(ft);            }        }        /// <summary>        /// 点击加入队列        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void btnTask1_Click(object sender, EventArgs e)        {            FileText ft = new FileText();            Button btn = sender as Button;            switch (btn.Name)            {                case "btnTask1":                    ft.pbName = "taskPro1";                    ft.startPro = 0;                    ft.endPro = 2500;                    lbPro1.Text = "等待中...";                    break;                case "btnTask2":                    ft.pbName = "taskPro2";                    ft.startPro = 0;                    ft.endPro = 3500;                    lbPro2.Text = "等待中...";                    break;                case "btnTask3":                    ft.pbName = "taskPro3";                    ft.startPro = 0;                    ft.endPro = 4000;                    lbPro3.Text = "等待中...";                    break;                case "btnTask4":                    ft.pbName = "taskPro4";                    ft.startPro = 0;                    ft.endPro = 3000;                    lbPro4.Text = "等待中...";                    break;                case "btnTask5":                    ft.pbName = "taskPro5";                    ft.startPro = 0;                    ft.endPro = 5000;                    lbPro5.Text = "等待中...";                    break;                case "btnTask6":                    ft.pbName = "taskPro6";                    ft.startPro = 0;                    ft.endPro = 4500;                    lbPro6.Text = "等待中...";                    break;                default:                    break;            }            StartRunEnqueueThread(ft);            isEnable(btn,false);        }        /// <summary>        /// 按钮是否可用        /// </summary>        /// <param name="btn"></param>        /// <param name="b"></param>        private void isEnable(Button btn,bool b)        {            this.Invoke(new Action(() => {                btn.Enabled = b;            }));        }        /// <summary>        /// 执行进队列线程操作        /// </summary>        /// <param name="ft"></param>        private void StartRunEnqueueThread(FileText ft)        {            Thread th = new Thread(new ParameterizedThreadStart(EnqueueMethod));            th.IsBackground = true;            th.Start(ft);        }        /// <summary>        /// 进队列方法,限制线程数        /// </summary>        /// <param name="ft"></param>        private void EnqueueMethod(object ft)        {            FileText fText = ft as FileText;            LimitSemaphore.WaitOne();//等待信号            EnqueueFile(fText);        }        #endregion        #region 析构函数释放资源        ~Form1()        {            Dispose();        }        /// <summary>        /// 释放资源        /// </summary>        private new void Dispose()        {            if (_FileQueue.Count > 0)                _FileQueue.Clear();            if (_FileList.Count > 0)                _FileList.Clear();            LimitSemaphore.Close();            System.Diagnostics.Process.GetCurrentProcess().Kill();        }        #endregion    }    #region 文件类    public class FileText    {        public string pbName { set; get; }        public int startPro { set; get; }        public int endPro { set; get; }    }    #endregion}


0 0
原创粉丝点击