多线程编程实例

时间:2022-09-09 18:24:20
 

  今天我想操作二十万左右数据,进行整体的修改,当然是进行了相当复杂运算的,如果单线程那就只有晚上执行了,但是急需看到结果,慢慢开始了今天的主题,多线程编程,个人不建议线程太多,我这里设置的  private readonly int thread = 10;//进程数 ;

先把效果图附上,

多线程编程实例确保是真实有效的,并不是忽悠。

接下来上代码了。

       delegate void SetTextCallback(System.Windows.Forms.Control ct, string text);
        delegate void SetTextCallback2(System.Windows.Forms.Control ct, int text);
        delegate void SetTextCallback3(System.Windows.Forms.Control ct, bool falt);

        #region 参数

        private readonly int thread = 10;//进程数      
        private int i = 0;//报告进度的累加器  
        private int sumcount = 0;
        Thread[] threadk;

        private readonly static object locker = new object();
          #endregion

      /// <summary>
        /// 开始执行

        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ChangeThreadeds();
        }

   #region 后台控制UI
        /// <summary>
        /// 显示执行的百分比
        /// </summary>
        /// <param name="ct"></param>
        /// <param name="text"></param>
        public void SetText(System.Windows.Forms.Control ct, string text)
        {
            //在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决

            while (!ct.IsHandleCreated)
            {
                ;
            }
            // InvokeRequired需要比较调用线程ID和创建线程ID
            // 如果它们不相同则返回true
            if (ct.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { ct, text });
            }
            else
            {
                ct.Text = text;
            }
        }
        /// <summary>
        /// 执行按钮是否可以与用户交互
        /// </summary>
        /// <param name="ct"></param>
        /// <param name="falt"></param>
        public void SetText2(System.Windows.Forms.Control ct, bool falt)
        {
            //在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
            while (!ct.IsHandleCreated)
            {
                ;
            }
            // InvokeRequired需要比较调用线程ID和创建线程ID
            // 如果它们不相同则返回true
            if (ct.InvokeRequired)
            {
                SetTextCallback3 d = new SetTextCallback3(SetText2);
                this.Invoke(d, new object[] { ct, falt });
            }
            else
            {
                (ct as Button).Enabled = falt;
            }
        }
        /// <summary>
        /// 显示进度条
        /// </summary>
        /// <param name="ct"></param>
        /// <param name="text"></param>
        public void SetText3(System.Windows.Forms.Control ct, int text)
        {
            //在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
            while (!ct.IsHandleCreated)
            {
                ;
            }
            // InvokeRequired需要比较调用线程ID和创建线程ID
            // 如果它们不相同则返回true
            if (ct.InvokeRequired)
            {
                SetTextCallback2 d = new SetTextCallback2(SetText3);
                this.Invoke(d, new object[] { ct, text });
            }
            else
            {
                (ct as ProgressBar).Value = text;
            }
        }

        public void SetText4(System.Windows.Forms.Control ct, string text)
        {
            //在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决

            while (!ct.IsHandleCreated)
            {
                ;
            }
            // InvokeRequired需要比较调用线程ID和创建线程ID
            // 如果它们不相同则返回true
            if (ct.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText4);
                this.Invoke(d, new object[] { ct, text });
            }
            else
            {
                ct.Text += text;
            }
        }
        #endregion

 

 #region 创建多线程
        /// <summary>
        /// 创建并且启动多条线程
        /// </summary>
        void ChangeThreadeds()
        { 

           SetText2(button1, false);
            sumcount = 1000; //ds.Tables.Count > 0 ? ds.Tables[0].Rows.Count : 0;
            threadk = new Thread[thread];
            for (int j = 0; j < thread; j++)
            {
                threadk[j] = new Thread(new ThreadStart(updateIvaddr));
                threadk[j].Name = "线程" + j.ToString();
                threadk[j].Start();
            }
        }

 /// <summary>
        /// 修改方法
        /// </summary>
        /// <param name="mo"></param>
        void updateIvaddr()
        {

         while (i<1000)
            {
                lock (locker)//记得加锁噢
                {
                     if(i>1000)  //记得是双重判断,不然会出问题,为什么你知道的。
                        break;
                    i++;                                      
                    zhixing(dr);
                    SetText(label1, ((i * 100) / sumcount).ToString() + "%");
                    SetText3(progressBar1, (i * 100) / sumcount);
                   
                }
            }
            SetText2(button1, true);
        }

 /// <summary>
        /// 执行整体方法
        /// </summary>
        void zhixing(DataRow dd)
        {

            SetText4(richTextBox1, Thread.CurrentThread.ManagedThreadId.ToString() + "=>" + Thread.CurrentThread.Name.ToString() + "\n");

}

        #endregion

代码奉献完毕,具体为什么大家一看就明白我相信,不是我们不会,而是我们没有实践,实践以后,相信我们是最棒的。

注:此代码是我程序用到,经过改变,为初学者提供的,为原创,请勿大家转载。谢谢