zoukankan      html  css  js  c++  java
  • C# 多线程控制控件实例(例程简单,注释详细)

    View Code
    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 System.Threading;

    namespace WindowsFormsApplication2
    {
        //定义委托
        public delegate void ListBoxDelegate(); 

        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }

            //委托处理方法(关联与ListBoxDelegate)
            private void ListBox()
            {
                if (!listBox1.InvokeRequired)//如果在UI主线程操作ListBox,
                {
                    //listBox1.Items.Add(++CommonData.num);//则直接进行控件操作,“与UI主线程相关联”
                    listBox1.Items.Add(CommonData.plus());//则直接进行控件操作,“与UI主线程相关联”
                    listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
                }
                else//如果是在另一线程操作ListBox,则启用委托
                    listBox1.Invoke(new ListBoxDelegate(listShow));
            }

            //定义对UI主线程控件的操作,“与AddAuto相关联”。
            private void listShow()
            {
                //listBox1.Items.Add(CommonData.num);
                listBox1.Items.Add(CommonData.plus());
                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
            }
            //定义线程函数
            private void AddAuto()
            {
                while (CommonData.Flag == 0)
                {
                    //CommonData.num++;
                    Thread.Sleep(1000);
                    ListBox();//不能直接控制UI上的控件,所以用该方法选择使用委托
                }
            }

            /// <summary>
            
    /// 在click事件中启动多线程
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void btnStart_Click_1(object sender, EventArgs e)
            {
                CommonData.Flag = 0;//线程标志置0,表示开启线程
                ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);//定义 ThreadStart的委托类型的参数,并使该委托指向线程函数
                Thread insertTxt = new Thread(new ThreadStart(mycn));//实例化线程
                insertTxt.Start();//启动线程
            }




            private void btnAbort_Click_1(object sender, EventArgs e)
            {
                CommonData.Flag = 1;
            }

            private void btnCtrlMain_Click_1(object sender, EventArgs e)
            {
                ListBox();
            }

            private void btnReset_Click_1(object sender, EventArgs e)
            {
                CommonData.num = 0;
            }

            private void btnClear_Click_1(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
            }

            private void btnQuit_Click_1(object sender, EventArgs e)
            {
                Application.Exit();
            }





        }
    }
    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace WindowsFormsApplication2
    {
        class CommonData
        {
            private static int _Flag = 0;
            private static int _num = 0;

            //CommonData.num只是完成了多线程控制主线程控件的功能,
            
    //如果能手动和自动同时访问全局变量时,就有可能出现线程不同步的问题。
            
    //以下主要利用lock线程锁来修改解决方案,使线程同步
            public static int plus()
            {
                lock (new object())
                {
                    return _num++;
                }
            }


            public static int Flag
            {
                get { return _Flag; }
                set { _Flag = value; }
            }
            public static int num
            {
                get { return _num; }
                set { _num = value; }
            }

        }
    }

    总结:

            要使用多线程控制UI控件,必须用委托实现。调用控件的Invoke方法(Invoke方法的参数是一个委托类型的参数)。

    实现步骤:

             1.声明委托。

              2.声明委托处理函数(判断是主线程控制UI控件,还是Invoke(多线程)控制UI控件)。

             3.声明一个线程实例,将线程函数的委托传入ThreadStart()。

             4.开启该线程。

             5.定义该线程函数,欲控制UI控件,则调用第2步的委托处理函数,他将自己判断选择用Invoke。

             6.定义Invoke需要调用的函数(如本例的listShow函数)

    //*********************************************************************************************************************************

          在上例中,只是完成了多线程控制主线程控件的功能,如果能手动和自动同时访问全局变量时,就有可能出现线程不同步的问题。以下主要利用lock线程锁来修改解决方案,使线程同步,注意代码带动的地方。

    http://www.cnblogs.com/kingkoo/archive/2009/05/02/1447728.html

    C#多线程中使用代理(委托)  

    http://blog.163.com/zhb123@126/blog/static/62515850201062714121186/

    View Code
    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 System.Threading;

    namespace WindowsFormsApplication2
    {
        public delegate void myDelegate1(string s);//1.定义委托

        public partial class TestThread : Form
        {
            public TestThread()
            {
                InitializeComponent();
            }
            //2.为修改进度条创建一个方法:
            private void SetProgressBar1(string s)
            {
                progressBar1.Value = 0;
                progressBar1.Maximum = 2;
                this.progressBar1.Value = this.progressBar1.Value + 1;
                MessageBox.Show("SetProgressBar1"+s);
            }
            //3.创建一个新线程并指向“TRun1”方法
            private void TRun1()
            {
               // 判断控件是否属于该线程

                 
    //判断控件是否在本线程内
                  if (!this.progressBar1.InvokeRequired)
                  {
                      Thread.Sleep(2000);
                  }
                else
                  {
                     myDelegate1 md1 = new myDelegate1(SetProgressBar1);//不属于该线程,创建一个代理,并将代理指向“SetProgressBar1”方法
                     Thread.Sleep(2000);//停顿2秒钟
                     
    //Invoke(md1);//Invoke代理,从而执行“SetProgressBar1”方法。(“SetProgressBar1”方法在主线程地址空间执行)
                     Invoke(md1, "TRun1");
                  }
            }
            //4.开启新线程调用:
            private void button1_Click(object sender, EventArgs e)
            {     
                 Thread thread = new Thread(new ThreadStart(TRun1));
                thread.Start();
                MessageBox.Show("使用多线程");
            }
        }
    }
  • 相关阅读:
    ASP.NET WebAPI Get和Post 传参总结
    关于EF第一次加载慢或过一段时间不访问时再次访问加载慢问题的总结
    jqthumb.js缩略图插件-让缩略图正常显示而不变形
    解决kindeditor编辑器中使用百度地图时不能拖动坐标的问题
    Jzoj3591 数据
    Jzoj3590 珠链
    Jzoj3590 珠链
    C++蜂鸣器歌曲1
    C++蜂鸣器歌曲1
    Jzoj2309 辽哥游戏
  • 原文地址:https://www.cnblogs.com/Snowfun/p/2862256.html
Copyright © 2011-2022 走看看